cover/Elixir.DaProductApp.QRValidation.Parser.ValQrParser.html

1 defmodule DaProductApp.QRValidation.Parser.ValQrParser do
2 @moduledoc """
3 Parses ReqValQr / RespValQr XML into normalized maps for persistence.
4 NOTE: Minimal subset implemented; extend as needed per spec.
5 """
6 import SweetXml
7
8 @type parsed :: map()
9
10 @spec parse_req(String.t()) :: {:ok, parsed()} | {:error, term()}
11 def parse_req(xml) when is_binary(xml) do
12
:-(
try do
13
:-(
doc = SweetXml.parse(xml)
14 {:ok,
15 %{
16 kind: :req_val_qr,
17 msg_id: xpath(doc, ~x"//Head/@msgId"s),
18 org_id: xpath(doc, ~x"//Head/@orgId"s),
19 txn_id: xpath(doc, ~x"//Txn/@id"s),
20 payer_addr: xpath(doc, ~x"//Payer/@addr"s),
21 payer_name: xpath(doc, ~x"//Payer/@name"s),
22 ver_token: nil,
23 raw_xml: xml
24 }}
25 rescue
26
:-(
e -> {:error, {:parse_error, e}}
27 end
28 end
29
30 @spec parse_resp(String.t()) :: {:ok, parsed()} | {:error, term()}
31 def parse_resp(xml) when is_binary(xml) do
32
:-(
try do
33
:-(
doc = SweetXml.parse(xml)
34
:-(
fx_nodes = xpath(doc, ~x"//FxList/Fx"l)
35
36
:-(
fx_quotes =
37 Enum.map(fx_nodes, fn node ->
38
:-(
%{
39 base_currency: xpath(node, ~x"./@baseCurr"s),
40 base_amount: to_decimal(xpath(node, ~x"./@baseAmount"s)),
41 fx_rate: to_decimal(xpath(node, ~x"./@Fx"s)),
42 markup_pct: to_decimal(xpath(node, ~x"./@Mkup"s)),
43 active: xpath(node, ~x"./@active"s) |> active_flag(),
44 last_modified_ts: parse_dt(xpath(node, ~x"./@lastModifedTs"s))
45 }
46 end)
47
48 {:ok,
49 %{
50 kind: :resp_val_qr,
51 msg_id: xpath(doc, ~x"//Head/@msgId"s),
52 org_id: xpath(doc, ~x"//Head/@orgId"s),
53 txn_id: xpath(doc, ~x"//Txn/@id"s),
54 ver_token: xpath(doc, ~x"//Qr/@verToken"s),
55 payer_addr: xpath(doc, ~x"//Payee/@addr"s),
56 payer_name: xpath(doc, ~x"//Payee/@name"s),
57 fx_quotes: fx_quotes,
58 raw_xml: xml
59 }}
60 rescue
61
:-(
e -> {:error, {:parse_error, e}}
62 end
63 end
64
65
:-(
defp to_decimal(""), do: nil
66
:-(
defp to_decimal(nil), do: nil
67 defp to_decimal(str) do
68
:-(
case Decimal.parse(str) do
69
:-(
{:ok, dec} -> dec
70
:-(
:error -> nil
71 end
72 end
73
74
:-(
defp active_flag("TRUE"), do: true
75
:-(
defp active_flag("true"), do: true
76
:-(
defp active_flag(_), do: false
77
78
:-(
defp parse_dt(""), do: nil
79
:-(
defp parse_dt(nil), do: nil
80 defp parse_dt(str) do
81
:-(
case DateTime.from_iso8601(str) do
82
:-(
{:ok, dt, _} -> dt
83
:-(
_ -> nil
84 end
85 end
86 end
Line Hits Source