Histórico da Página
...
Para acessar o valor de um campo do formulário utilizar a API do workflow hAPI.getCardValue(<nomeCampo>) e para o tratamento de exeções utilizar o comando throw <mensagem> que apresentará a mensagem para o usuário impendindo que prossiga enquanto não corrigir as informações digitadas.
Script do evento no ECM
Validações simples podem ser realizadas no script do evento para evitar a comunicação desnecessário ao Protheus retornando imediatamente uma mensagem ao usuário.
function beforeTaskSave(colleagueId,nextSequenceId,userList){
var A1_COD = hAPI.getCardValue("A1_COD");
if (A1_COD == ""){
throw "O campo Código é obrigatório"
}
}
Protheus
A validação nos scripts dos eventos utilizando aplicações externas é realizada atraves de WebServices que devem ser cadastradas como serviço no ECM na opção Painel de Controle > Serviços > Adicionar. Quando qualquer definição do WebService for alterada ou incluída será necessário atualizar o ECM na opção Painel de Controle > Serviços > Editar > Atualizar.
O WebService pode ser cadastrado através do Painel de Controle do ECM ou pelo Protheus utilizando a função FWWFPutService como no exemplo abaixo.
#include "totvs.ch"
User Function WSCliente()
Local cName := "WSCLIENTE"
Local cURL := "http://hostname:8080/ws/exemplo.apw?wsdl"
Local cDescription := "Serviço para validação e atualização do cadastro de cliente"
If FWWFPutService(cName,cUrl,cDescription)
MsgInfo("Serviço cadastrado com sucesso")
EndIf
Return
WebService
Para maiores informações sobre como desenvolver Web Services com o Microsiga Protheus, consulte o link: Web Services com o ERP Microsiga Protheus.
Exemplo de WebService do Protheus:
#include "totvs.ch"
#include "apwebsrv.ch"
WSSERVICE WSCLIENTE DESCRIPTION "Exemplo cadastro de cliente"
WSDATA A1_COD AS STRING
WSDATA A1_LOJA AS STRING
WSDATA XML AS Base64Binary
WSDATA RETEXISTCOD AS BOOLEAN
WSDATA RETINCLUIR AS BOOLEAN
WSMETHOD ExistCod DESCRIPTION "Verifica se codigo do cliente ja existe"
WSMETHOD Incluir DESCRIPTION "Inclui cliente"
ENDWSSERVICE
WSMETHOD ExistCod WSRECEIVE A1_COD,A1_LOJA WSSEND RETEXISTCOD WSSERVICE WSCLIENTE
Private INCLUI := .T.
::RETEXISTCOD := existchav("SA1",::A1_COD+::A1_LOJA)
Return .T.
WSMETHOD Incluir WSRECEIVE XML WSSEND RETINCLUIR WSSERVICE WSCLIENTE
Local oXML := tXMLManager():New()
Local lRet := .T.
Local aDadosCli := {}
If oXML:Parse(::XML)
aAdd( aDadosCli, { "A1_COD" , oXML:XPathGetNodeValue("/SA1/A1_COD") , NIL } )
aAdd( aDadosCli, { "A1_LOJA" , oXML:XPathGetNodeValue("/SA1/A1_LOJA") , NIL } )
aAdd( aDadosCli, { "A1_TIPO" , oXML:XPathGetNodeValue("/SA1/A1_TIPO") , NIL } )
aAdd( aDadosCli, { "A1_PESSOA" , oXML:XPathGetNodeValue("/SA1/A1_PESSOA"), NIL } )
aAdd( aDadosCli, { "A1_NOME" , oXML:XPathGetNodeValue("/SA1/A1_NOME") , NIL } )
aAdd( aDadosCli, { "A1_NREDUZ" , oXML:XPathGetNodeValue("/SA1/A1_NREDUZ"), NIL } )
aAdd( aDadosCli, { "A1_END" , oXML:XPathGetNodeValue("/SA1/A1_END") , NIL } )
aAdd( aDadosCli, { "A1_MUN" , oXML:XPathGetNodeValue("/SA1/A1_MUN") , NIL } )
aAdd( aDadosCli, { "A1_EST" , oXML:XPathGetNodeValue("/SA1/A1_EST") , NIL } )
lMsErroAuto := .F.
MSExecAuto( { | x, y | MATA030( x, y ) } , aDadosCli, 3 )
If lMsErroAuto
If __lSX8
RollBackSX8()
EndIf
::RETINCLUIR := .F.
Else
If __lSX8
ConFirmSX8()
EndIf
::RETINCLUIR := .T.
EndIf
Else
SetSoapFault("WSCLIENTE:INCLUIR",oXML:LastError())
lRet := .F.
EndIf
Return lRet
Validação no script do evento beforeTaskSave:
- Invocar a carga do serviço com o método ServiceManager.getService
- Utilizar o método getBean para retornar o utilitário para acesso as classes do serviço através do método instantiate enviando como parâmetro a classe Locator que esta descrita no ECM em Painel de Controle > Serviços, selecionar o serviço e clicar em Visualizar
- Invocar o método para instanciar o serviço (no exemplo getWSCLIENTESOAP) que também esta descrito na opção Painel de Controle > Serviços > Visualizar
- Invocar o método do serviço (no exemplo ExistCod)
function beforeTaskSave(colleagueId,nextSequenceId,userList){
var A1_COD = hAPI.getCardValue("A1_COD");
if (A1_COD == ""){
throw "O campo Código é obrigatório"
}
var wsService = ServiceManager.getService("WSCLIENTE");
var serviceHelper = wsService.getBean();
var serviceLocator = serviceHelper.instantiate("localhost.WSCLIENTELocator");
var service = serviceLocator.getWSCLIENTESOAP();
var ret = false;
try {
ret = service.EXISTCOD(A1_COD);
}
catch(erro){
throw erro.message
}
if (!ret) {
throw "Cliente já existe";
}
}
MVC
A validação do processo de uma rotina MVC é realizada utilizando o WebService FWWSMODEL (http://hostexemplo:8080/ws/fwwsmodel.apw?wsdl) com a invocação do método GETXMLDATADETAIL que retorna o XML do model para popular os dados e do método VLDXMLDATA que validará o XML.
#include "totvs.ch"
User Function WSMVC()
Local cName := "TOTVS_FWMVC"
Local cURL := "http://hostname:8080/ws/fwwsmodel.apw?wsdl "
Local cDescription := "Serviço do TOTVS MVC para integração de rotinas/programas com ECM"
Local aService := FWWFGetService(cName)
If Empty(aService) .and. FWWFPutService(cName,cUrl,cDescription)
MsgInfo("Serviço cadastrado com sucesso")
EndIf
Return
Validação no script do evento beforeTaskSave:
function beforeTaskSave(colleagueId,nextSequenceId,userList){
var wsService = ServiceManager.getService("TOTVS_FWMVC");
var serviceHelper = wsService.getBean();
var serviceLocator = serviceHelper.instantiate("br.com.totvs.webservices.fwwsmodel_apw.FWWSMODELLocator");
var service = serviceLocator.getFWWSMODELSOAP();
var err = {message:"", empty:true};
var ret, xml;
try {
ret = service.GETXMLDATADETAIL([],"MATA030_MVC");
xml = new XML(new String(new java.lang.String(ret)).replace(/<\?.*\?>/g,""));
}
catch(erro){
throw erro.message;
return;
}
updateXMLFields(xml,err);
if (err.message.length > 0){
throw err.message;
}
else if (err.empty){
throw "Preencha o formulário";
}
else{
eval("xml.@Operation = 3");
try{
service.VLDXMLDATA([],"MATA030_MVC",new java.lang.String(xml.toXMLString()).getBytes());
} catch(e){
throw e.message;
}
}
}
function updateXMLFields(node,err){
var list = node.children();
var name,value;
for (var i=0;i<list.length();i++){
switch (Trim(eval("list[i][email protected]()"))){
case "FIELDS":
updateXMLFields(list[i],err);
break;
default:
name = list[i].name().localName;
value = hAPI.getCardValue(name);
if (value != null)
list[i].value = convertValue(name,list[i],value,err);
break;
}
if (err.message.length > 0)
break;
}
}
function convertValue(name,struct,value,err){
var y,m,d,n,len,str,reg
var setYear = new Date().getFullYear().toString().substring(0,2);
var setDate = "dd/mm/yyyy";
var yCount = setDate.match(/yyyy/) ? 4 : 2;
var hasErr = false;
value = value.trim();
switch (eval("[email protected]()")){
case "D":
if (value.replace("/","").trim() != ""){
len = value.length();
d = setDate.indexOf("d");
m = setDate.indexOf("m");
y = setDate.indexOf("y");
if (d + 2 > len || m + 2 > len || y + yCount > len){
hasErr = true;
}
else{
str = value.substr(m,2) + value.substr(d,2);
if (yCount == 4)
str = value.substr(y,4) + str;
else
str = setYear + value.substr(y,2) + str;
if (str.match(/((((19|20)(([02468][048])|([13579][26]))0229))|((19|20)[0-9][0-9])((((0[1-9])|(1[0-2]))((0[1-9])|(1\d)|(2[0-8])))|((((0[13578])|(1[02]))31)|(((0[1,3-9])|(1[0-2]))(29|30)))))/g))
value = new java.lang.String(str);
else
hasErr = true;
}
if (hasErr)
err.message = "O campo "+eval("struct.@info")+" ("+name+") contém uma data inválida";
else
err.empty = false;
}
break;
case "N":
len = eval("[email protected]().split(',')");
if (len[1] == "0"){
reg = new RegExp("^[0-9]{1,"+len[0]+"}$");
str = value.replace(",","");
if(!reg.test(str)){
str = value.replace(".","");
if(!reg.test(str)){
err.message = "O campo "+eval("struct.@info")+" ("+name+") contém um número (valor ou tamanho) inválido"
hasErr = true;
break;
}
}
if (!hasErr){
n = parseInt(str);
if (!isNaN(n)){
value = new java.lang.String(str);
if (n > 0)
err.empty = false;
}
}
}
else{
reg = new RegExp("^0$|^0\.[0-9]{1,"+len[1]+"}$|^[0-9]{0,"+len[0]+"}(\.[0-9]{1,"+len[1]+"})?$");
str = value.replace(".","").replace(",",".");
if(!reg.test(str)){
str = value.replace(",","");
if(!reg.test(str)){
err.message = "O campo "+eval("struct.@info")+" ("+name+") contém um número (valor ou tamanho) inválido"
hasErr = true;
break;
}
}
if (!hasErr){
n = parseFloat(str);
if (!isNaN(n)){
value = new java.lang.String(str);
if (n > 0)
err.empty = false;
}
}
}
break;
default:
if (value != "")
err.empty = false;
break;
}
return value;
}
function Trim(str){return str.replace(/^\s+|\s+$/g,"");}