defmodule CorreiosEx.Services do
require Logger
import SweetXml
@type requestParams :: %{
contract_number: :string,
post_card_number: :string,
sigep_user: :string,
sigep_password: :string
}
@type service :: %{
code: :integer,
name: :string
}
@headers [{"Content-Type", "application/soap+xml"}]
@endpoint "https://apps.correios.com.br/SigepMasterJPA/AtendeClienteService/AtendeCliente"
@spec list_services(requestParams) :: {:ok, [service]} | {:error, term()}
def list_services(params) do
case HTTPoison.post(@endpoint, build_body(params), @headers) do
{:ok, %HTTPoison.Response{status_code: 200, body: body}} ->
parse_response(body)
{:ok, %HTTPoison.Response{body: body}} ->
response_error = xpath(body, ~x"//faultstring/text()"s)
{:error, "A chamada retornou com erro: #{response_error}"}
_ ->
Logger.error("Unknow error to get correios services")
{:error, "erro desconecido, por favor tente novamente mais tarde"}
end
end
defp parse_response(body) do
services_node = xpath(body, ~x"//return"l)
{
:ok,
Enum.map(services_node, fn service_node ->
%{
code: xpath(service_node, ~x"./codigo/text()"s |> transform_by(&String.trim/1)),
name:
xpath(
service_node,
~x"./descricao/text()"s |> transform_by(&String.trim/1)
)
}
end)
}
end
defp build_body(config) do
"""
<x:Envelope xmlns:x="http://schemas.xmlsoap.org/soap/envelope/" xmlns:cli="http://cliente.bean.master.sigep.bsb.correios.com.br/">
<x:Header/>
<x:Body>
<cli:buscaServicos>
<idContrato>#{config.contract_number}</idContrato>
<idCartaoPostagem>#{config.post_card_number}</idCartaoPostagem>
<usuario>#{config.sigep_user}</usuario>
<senha>#{config.sigep_password}</senha>
</cli:buscaServicos>
</x:Body>
</x:Envelope>
"""
end
end