I'm just a junior, and I'm taking care of a support project alone, and with many doubts. I have a plugin made, which connects the dynamics with the SAP system. every occurrence created within the dynamics, automatically has to create a protocol in SAP. Most is working, but in some cases it is not integrating. We have an integration log to track, and the message it gives is "Data at the root level is invalid. Line 1, position 1." What could it be, and how could I check what's happening in real time?
I appreciate any help
SERVICE INTEGRATION SAP
public class IntegracaoSap
{
private object service;
public string XmlSapRetonro { get; private set; }
public IntegracaoSap(object provider)
{
this.service = provider;
}
public string OrganizationName { get; set; }
private static readonly Regex _tags_ = new Regex(@"<[^>]+?>", RegexOptions.Multiline | RegexOptions.Compiled);
//add characters that are should not be removed to this regex
private static readonly Regex _notOkCharacter_ = new Regex(@"[^\w;&#@.:/\\?=|%!() -]", RegexOptions.Compiled);
public string EnviarProtocolo(Ocorrencia ocorrencia, VariavelAmbiente variavelAmbiente, Email email)
{
if (ocorrencia == null)
{
throw new Exception("Ocorrência não informada.");
}
var emailAssunto = "";
var response = String.Empty;
var msgRetorno = String.Empty;
var remetente = "Remetente: ";
var assunto = "Assunto: ";
var descricaoAssunto = "";
var modeAssuntoRemetente = "";
var emailCliente = string.Empty;
if (email != null)
{
if (email.De[0].Type.Equals("account", StringComparison.InvariantCultureIgnoreCase))
{
var conta = new Conta("", service).ObterPorId(email.De[0].Id);
emailCliente = conta.Email;
}
else if (email.De[0].Type.Equals("contact", StringComparison.InvariantCultureIgnoreCase))
{
var contato = new Contato("", service).ObterPor(email.De[0].Id);
emailCliente = contato.Email;
}
emailAssunto = Regex.Replace(email.Assunto, @"<[^>]*(>|$)| |‌|»|«", string.Empty).Trim();
modeAssuntoRemetente = remetente + email.De[0].Name + " " + " " + emailCliente + " " + " " + "\n" + assunto + " " + "\n" + emailAssunto;
}
else
{
//pegar email de Contato em Ocorrencia
if(ocorrencia.Cliente.Type.Equals("account",StringComparison.InvariantCultureIgnoreCase))
{
var conta = new Conta("", service).ObterPorId(ocorrencia.Cliente.Id);
emailCliente = conta.Email;
}
else if (ocorrencia.Cliente.Type.Equals("contact", StringComparison.InvariantCultureIgnoreCase))
{
var contato = new Contato("", service).ObterPor(ocorrencia.Cliente.Id);
emailCliente = contato.Email;
}
descricaoAssunto = Regex.Replace(ocorrencia.Descricao, @"<[^>]*(>|$)| |‌|»|«", string.Empty).Trim();
modeAssuntoRemetente = remetente + ocorrencia.Cliente.Name + " " + "\n" + emailCliente + " " + "\n" + descricaoAssunto;
}
modeAssuntoRemetente = GetSubstring(modeAssuntoRemetente);
string usuario = variavelAmbiente.ObterValorPor("b2bsac_usuario_sap").ToString();
string senha = variavelAmbiente.ObterValorPor("b2bsac_senha_sap").ToString();
string P_DESCRIPTION = string.Empty;
try
{
string url = variavelAmbiente.ObterValorPor("b2bsac_url_sap_ocorrencia").ToString();
string sapStatus = variavelAmbiente.ObterValorPor("b2bsac_sap_pstatus").ToString();
string processType = variavelAmbiente.ObterValorPor("b2bsac_sap_processtype").ToString();
string category = variavelAmbiente.ObterValorPor("b2bsac_sap_category").ToString();
string codeGroup = variavelAmbiente.ObterValorPor("b2bsac_sap_codegroup").ToString();
WebRequest httpWebRequest = WebRequest.Create(url);
httpWebRequest.ContentType = "application/xml";
httpWebRequest.Headers["Ocp-Apim-Subscription-Key"] = variavelAmbiente.ObterValorPor("b2bsac_value_sap").ToString();
httpWebRequest.Headers["SOAPAction"] = "http://sap.com/xi/WebService/soap1.1";
httpWebRequest.Method = "POST";
httpWebRequest.Headers["Authorization"] = "Basic " + Convert.ToBase64String(Encoding.Default.GetBytes($"{usuario}:{senha}"));
using (var streamWriter = new StreamWriter(httpWebRequest.GetRequestStream()))
{
var xml = "<soapenv:Envelope xmlns:soapenv=\"http://schemas.xmlsoap.org/soap/envelope/\" xmlns:urn=\"urn:energiasdobrasil-com-br.URA_PROTOCOLO\">" +
" <soapenv:Header/>" +
" <soapenv:Body>" +
"<urn:mt_ura_protocolo>" +
"<IV_BU_PARTNER></IV_BU_PARTNER>" +
"<IV_PROCESS_TYPE>" + processType + "</IV_PROCESS_TYPE>" +
"<IV_DIRECTION>0</IV_DIRECTION>" +
"<IV_CATEGORY>" + category + "</IV_CATEGORY>" +
"<P_STATUS>" + sapStatus +"</P_STATUS>" +
"<P_DESCRIPTION>PROTOCOLO E-MAIL</P_DESCRIPTION>" +
"<P_CODE_GROUP>" + codeGroup + "</P_CODE_GROUP>" +
"<P_CODE>PR01</P_CODE>" +
"<P_FUNC_PARC>ZP000010</P_FUNC_PARC>" +
"<P_FUNC_PARC_RESP>ZP000011</P_FUNC_PARC_RESP>" +
"<P_RESP>CRM_DYN</P_RESP>" +
"<P_DATA>" +
"<REF_GUID></REF_GUID>" +
"<REF_HANDLE></REF_HANDLE>" +
"<REF_KIND></REF_KIND>" +
"<APPT_TYPE></APPT_TYPE>" +
"<TIMESTAMP_FROM></TIMESTAMP_FROM>" +
"<TIMEZONE_FROM></TIMEZONE_FROM>" +
"<TIMESTAMP_TO></TIMESTAMP_TO>" +
"<TIMEZONE_TO></TIMEZONE_TO>" +
"<DATE_FROM>" + ocorrencia.CriadoEm.Value.ToString("yyyyMMdd") + "</DATE_FROM>" +
"<DATE_TO>" + ocorrencia.CriadoEm.Value.ToString("yyyyMMdd") + "</DATE_TO>" +
"<TIME_FROM>" + ocorrencia.CriadoEm.Value.ToString("hhmmss") + "</TIME_FROM>" +
"<TIME_TO>" + ocorrencia.CriadoEm.Value.ToString("hhmmss") + "</TIME_TO>" +
"<SHOW_LOCAL></SHOW_LOCAL>" +
"<DOMINANT></DOMINANT>" +
"<RULE_ID></RULE_ID>" +
"<RULE_NAME></RULE_NAME>" +
"<DURATION></DURATION>" +
"<TIME_UNIT></TIME_UNIT>" +
"<IS_DURATION></IS_DURATION>" +
"<MODE></MODE>" +
"</P_DATA>" +
"<P_INSTALLATION></P_INSTALLATION>" +
"<P_NOTIFICATION></P_NOTIFICATION>" +
"<P_SALESDOCUMENT></P_SALESDOCUMENT>" +
"<P_OBJECTIVE>011</P_OBJECTIVE>" +
"<P_ATIVIDADE_PREC></P_ATIVIDADE_PREC>" +
"<P_BUT0ID>" +
"<PARTNER></PARTNER>" +
"<TYPE></TYPE>" +
"<IDNUMBER></IDNUMBER>" +
"</P_BUT0ID>" +
"<P_LOCATION></P_LOCATION>" +
"<P_ATIVIDADE_EXTERNA>" + ocorrencia.NumeroOcorrencia + "</P_ATIVIDADE_EXTERNA>" +
"<P_TELEFONE_URA></P_TELEFONE_URA>" +
"<P_TEXTO>" +
"<!--Zero or more repetitions:-->" +
"<item>" +
"<REF_GUID></REF_GUID>" +
"<REF_HANDLE></REF_HANDLE>" +
"<REF_KIND></REF_KIND>" +
"<TDID>A002</TDID>" +
"<TDSPRAS></TDSPRAS>" +
"<LANGU_ISO></LANGU_ISO>" +
"<TDSTYLE></TDSTYLE>" +
"<TDFORM></TDFORM>" +
"<TDFORMAT>*</TDFORMAT>" +
"<TDLINE>" + modeAssuntoRemetente + "</TDLINE>" +
"<MODE></MODE>" +
"</item>" +
"</P_TEXTO>" +
"</urn:mt_ura_protocolo>" +
"</soapenv:Body>" +
"</soapenv:Envelope>";
streamWriter.Write(xml);
}
var httpResponse = (HttpWebResponse)httpWebRequest.GetResponse();
var encoding = ASCIIEncoding.UTF8;
using (var reader = new System.IO.StreamReader(httpResponse.GetResponseStream(), encoding))
{
response = reader.ReadToEnd();
msgRetorno = response;
this.XmlSapRetonro = response;
}
}
catch (Exception ex)
{
msgRetorno = $"Ocorreu um erro no método EnviarProtocolo: {ex.Message}";
}
return msgRetorno;
}
public static String UnHtml(String html)
{
html = HttpUtility.UrlDecode(html);
html = HttpUtility.HtmlDecode(html);
html = RemoveTag(html, "<!--", "-->");
html = RemoveTag(html, "<script", "</script>");
html = RemoveTag(html, "<style", "</style>");
//replace matches of these regexes with space
html = _tags_.Replace(html, " ");
html = _notOkCharacter_.Replace(html, " ");
html = SingleSpacedTrim(html);
return html;
}
private static String RemoveTag(String html, String startTag, String endTag)
{
Boolean bAgain;
do
{
bAgain = false;
Int32 startTagPos = html.IndexOf(startTag, 0, StringComparison.CurrentCultureIgnoreCase);
if (startTagPos < 0)
continue;
Int32 endTagPos = html.IndexOf(endTag, startTagPos + 1, StringComparison.CurrentCultureIgnoreCase);
if (endTagPos <= startTagPos)
continue;
html = html.Remove(startTagPos, endTagPos - startTagPos + endTag.Length);
bAgain = true;
} while (bAgain);
return html;
}
private static String SingleSpacedTrim(String inString)
{
StringBuilder sb = new StringBuilder();
Boolean inBlanks = false;
foreach (Char c in inString)
{
switch (c)
{
case '\r':
case '\n':
case '\t':
case ' ':
if (!inBlanks)
{
inBlanks = true;
sb.Append(' ');
}
continue;
default:
inBlanks = false;
sb.Append(c);
break;
}
}
return sb.ToString().Trim();
}
public static string GetSubstring(string modeAssuntoRemetente)
{
string valorTexto = modeAssuntoRemetente;
// Pega os 132 caracteres da String
valorTexto = valorTexto.PadRight(132, ' ').Substring(0, 132);
return valorTexto;
}
}
}
OCURRENCE
public class OcorrenciaManager : IPlugin
{
public void Execute(IServiceProvider serviceProvider)
{
#region Contexto e Serviços
// Obtain the execution context from the service provider.
IPluginExecutionContext context = (IPluginExecutionContext)serviceProvider.GetService(typeof(IPluginExecutionContext));
// Obtain the organization service reference which you will need for
// web service calls.
IOrganizationServiceFactory serviceFactory = (IOrganizationServiceFactory)serviceProvider.GetService(typeof(IOrganizationServiceFactory));
IOrganizationService adminService = serviceFactory.CreateOrganizationService(null);
IOrganizationService userService = serviceFactory.CreateOrganizationService(context.UserId);
// Obtain the tracing service
ITracingService trace = (ITracingService)serviceProvider.GetService(typeof(ITracingService));
#endregion
adminService.SetDistribution(Distribution.Online);
Entity entidadeDoContexto = SDKorePlugin.GetContextEntity(context);
if (SDKorePlugin.Validate(context, SDKorePlugin.MessageName.Create, SDKorePlugin.Stage.PostOperation, SDKorePlugin.Mode.Asynchronous))
{
Ocorrencia ocorrencia = entidadeDoContexto.Parse<Ocorrencia>(context.OrganizationName, context.IsExecutingOffline, adminService);
Email email = new Email(context.OrganizationName, adminService).BuscarPrimeiroEmailOcorrencia(ocorrencia.Id.Value);
var logIntegracao = new LogIntegracao(context.OrganizationName, adminService);
var variavelAmbiente = new VariavelAmbiente(context.OrganizationName, adminService);
trace.Trace("Início da integração de consulta Ocorrencia");
if (entidadeDoContexto.Attributes.Contains("ticketnumber") && entidadeDoContexto.Attributes.Contains("description"))
{
trace.Trace("Início da integração de consulta Ocorrencia");
ocorrencia.CriarXMLParaSap(ocorrencia,variavelAmbiente,email);
}
}
}
}
}
MODEL
[LogicalEntity("incident")]
public class Ocorrencia : SDKoreBase
{
#region Construtores
public IOrganizationService service;
public Ocorrencia(string organization)
: base(organization)
{
RepositorioOcorrencia = new RepositoryOcorrencia<Ocorrencia>();
}
public Ocorrencia(string organization, object provider)
: base(organization, provider)
{
RepositorioOcorrencia = new RepositoryOcorrencia<Ocorrencia>();
RepositorioOcorrencia.SetOrganization(organization);
this.SetProvider(provider);
}
private void SetProvider(object provider)
{
RepositorioOcorrencia.SetProvider(provider);
this.Provider = provider;
}
#endregion
#region Atributos
private RepositoryOcorrencia<Ocorrencia> RepositorioOcorrencia { get; set; }
[LogicalAttribute("customerid")]
public Lookup Cliente { get; set; }
[LogicalAttribute("incidentid")]
public Guid? Id { get; set; }
[LogicalAttribute("ticketnumber")]
public string NumeroOcorrencia { get; set; }
[LogicalAttribute("description")]
public string Descricao { get; set; }
[LogicalAttribute("b2bsac_integracaoSAP")]
public Option Sac_Integracaosap { get; set; }
[LogicalAttribute("emailaddress")]
public string Email { get; set; }
#endregion
#region Métodos
public Ocorrencia ObterPorNumOcorrencia(string NumeroOcorrencia)
{
Ocorrencia _ocorrencia = null;
_ocorrencia = RepositorioOcorrencia.BuscarPorOcorrencia(NumeroOcorrencia);
return _ocorrencia;
}
public Ocorrencia ObterPor(Guid ocorrenciaId)
{
return RepositorioOcorrencia.Retrieve(ocorrenciaId);
}
public Guid Criar()
{
return RepositorioOcorrencia.Create(this);
}
public void Atualizar()
{
RepositorioOcorrencia.Update(this);
}
public void CriarXMLParaSap(Ocorrencia ocorrencia, VariavelAmbiente variavelAmbiente, Email email)
{
string response = string.Empty;
string MsgError = string.Empty;
try
{
var ocorrenciaAtualizar = new Ocorrencia("", this.Provider);
ocorrenciaAtualizar.Id = ocorrencia.Id;
ocorrenciaAtualizar.Sac_Integracaosap = new Option((int)Enumerator.IntegracaoSAP.EnviadoParaSap);
ocorrenciaAtualizar.Atualizar();
var integracaoSAP = new IntegracaoSap(this.Provider);
response = integracaoSAP.EnviarProtocolo(ocorrencia, variavelAmbiente, email);
var logIntegracao = new LogIntegracao("", this.Provider);
try
{
XmlDocument xDoc = new XmlDocument();
xDoc.LoadXml(response);
if (xDoc.SelectSingleNode("//P_MSG_RETORNO") != null)
{
if (xDoc.GetElementsByTagName("P_MSG_RETORNO").Item(0) != null)
{
MsgError = xDoc.GetElementsByTagName("P_MSG_RETORNO").Item(0).InnerText;
}
}
if ((MsgError != "Atividade criada !"))
{
ocorrenciaAtualizar.Sac_Integracaosap = new Option((int)Enumerator.IntegracaoSAP.NaoIntegradoComSap);
ocorrenciaAtualizar.Atualizar();
logIntegracao.Mensagem = MsgError;
if (!string.IsNullOrEmpty(integracaoSAP.XmlSapRetonro))
{
if (integracaoSAP.XmlSapRetonro.Length <= 9000)
{
logIntegracao.Mensagem += integracaoSAP.XmlSapRetonro;
}
else
{
logIntegracao.Mensagem += integracaoSAP.XmlSapRetonro.Substring(0, 8999);
}
}
logIntegracao.NumeroTentativas = 1;
logIntegracao.NomeSap = "";
logIntegracao.Ocorrencia = new SDKore.DomainModel.Lookup(ocorrencia.Id.Value, "incident");
logIntegracao.Criar();
}
else
{
ocorrenciaAtualizar.Sac_Integracaosap = new Option((int)Enumerator.IntegracaoSAP.IntegradoComSap);
ocorrenciaAtualizar.Atualizar();
}
}
catch(Exception ex)
{
ocorrenciaAtualizar.Sac_Integracaosap = new Option((int)Enumerator.IntegracaoSAP.NaoIntegradoComSap);
ocorrenciaAtualizar.Atualizar();
logIntegracao.Mensagem = ex.Message;
if (!string.IsNullOrEmpty(integracaoSAP.XmlSapRetonro))
{
if (integracaoSAP.XmlSapRetonro.Length <= 9000)
{
logIntegracao.Mensagem += integracaoSAP.XmlSapRetonro;
}
else
{
logIntegracao.Mensagem += integracaoSAP.XmlSapRetonro.Substring(0, 8999);
}
}
logIntegracao.NumeroTentativas = 1;
logIntegracao.NomeSap = "";
logIntegracao.Ocorrencia = new SDKore.DomainModel.Lookup(ocorrencia.Id.Value, "incident");
logIntegracao.Criar();
}
}
catch (Exception ex)
{
throw new InvalidPluginExecutionException(ex.Message);
}
}
#endregion
}
}