defmodule DaProductAppWeb.Services.EventLogger do require Logger alias DaProductApp.Activity.{CustomEvents, CustomEventsLog} alias DaProductApp.Users.User alias DaProductApp.Repo def store_event_and_log(event_name, params, amount_param, merchant_ref_number, refrence_id, transaction_id \\ nil, username \\ nil) do payload = if event_name == "Response Received From Middle layer" do build_qr_display_event_payload(params, amount_param, merchant_ref_number, refrence_id, username) else build_event_payload(params, amount_param, merchant_ref_number, refrence_id, username) end payload = case event_name do "Response Received From Middle layer" -> build_qr_display_event_payload(params, amount_param, merchant_ref_number, refrence_id, username) "Request For Publish Txn In MQTT" -> build_request_for_published_qr_code_payload(params, amount_param, merchant_ref_number, refrence_id, username) "Response From Publish Txn In MQTT" -> build_response_from_publish_qr_code_payload(params, amount_param, merchant_ref_number, refrence_id, username) "Response From Device Online Status" -> build_response_from_device_status_payload(params, amount_param, merchant_ref_number, refrence_id, username) "Request For Publish Txn" -> build_request_device_for_publish_qr_payload(params, amount_param, merchant_ref_number, refrence_id, username) "Response From Publish Txn" -> build_response_from_publish_device_qr_payload(params, amount_param, merchant_ref_number, refrence_id, username) _ -> build_event_payload(params, amount_param, merchant_ref_number, refrence_id, username) end with {:ok, event_id} <- store_custom_event(event_name, payload), {:ok, log_id} <- store_custom_event_log(event_id, event_name, payload, merchant_ref_number, refrence_id, transaction_id) do {:ok, event_id} else {:error, _} = err -> err end end defp build_event_payload(params, amount_param, merchant_ref_number, refrence_id, username) do payload = %{ amount: amount_param, username: username, app_key: Map.get(params, "appKey"), account_label: Map.get(params, "accountLabel"), customer_mobile_number: Map.get(params, "customerMobileNumber"), external_ref_number: Map.get(params, "externalRefNumber"), external_ref_number_2: Map.get(params, "externalRefNumber2"), external_ref_number_4: Map.get(params, "externalRefNumber4"), external_ref_numbers: Map.get(params, "externalRefNumbers"), push_to: Map.get(params, "pushTo") } if merchant_ref_number, do: Map.put(payload, :merchant_ref_number, merchant_ref_number), else: payload end defp build_qr_display_event_payload(params, amount_param, merchant_ref_number, refrence_id, username) do Logger.info("QR Display Event Params: #{inspect(params, pretty: true)}") payload = %{ amount: amount_param, status: Map.get(params, "status"), refrence_id: Map.get(params, "transaction_refid"), merchant_ref_number: Map.get(params, "mRefId"), qrCodeId: Map.get(params, "qrCodeId"), qrId: Map.get(params, "qrId"), transaction_id: Map.get(params, "transaction_id"), device_id: Map.get(params, "deviceSerial"), username: username } Logger.info("QR Display Event Payload: #{inspect(payload, pretty: true)}") if merchant_ref_number, do: Map.put(payload, :merchant_ref_number, merchant_ref_number), else: payload end defp build_request_for_published_qr_code_payload(params, amount_param, merchant_ref_number, refrence_id, username) do payload = %{ amount: amount_param, device_id: Map.get(params, :device_id), qrcode: Map.get(params, :qrcode), topic: Map.get(params, :topic), ts: Map.get(params, :ts), username: username } if merchant_ref_number, do: Map.put(payload, :merchant_ref_number, merchant_ref_number), else: payload end defp build_response_from_publish_qr_code_payload(params, amount_param, merchant_ref_number, refrence_id, username) do payload = %{ amount: amount_param, device_id: Map.get(params, :device_id), qrcode: Map.get(params, :qrcode), topic: Map.get(params, :topic), ts: Map.get(params, :ts), username: username, ref: Map.get(params, :ref), status: Map.get(params, :status), error: Map.get(params, :error), reason: Map.get(params, :reason) } if merchant_ref_number, do: Map.put(payload, :merchant_ref_number, merchant_ref_number), else: payload end defp build_response_from_device_status_payload(params, amount_param, merchant_ref_number, refrence_id, username) do payload = %{ amount: amount_param, device_id: Map.get(params, :device_id), status: Map.get(params, :status), ts: Map.get(params, :ts), username: username } if merchant_ref_number, do: Map.put(payload, :merchant_ref_number, merchant_ref_number), else: payload end defp build_request_device_for_publish_qr_payload(params, amount_param, merchant_ref_number, refrence_id, username) do payload = %{ amount: amount_param, device_id: Map.get(params, :device_id), ts: Map.get(params, :ts), username: username, topic: Map.get(params, :topic), qos: Map.get(params, :qos) } if merchant_ref_number, do: Map.put(payload, :merchant_ref_number, merchant_ref_number), else: payload end defp build_response_from_publish_device_qr_payload(params, amount_param, merchant_ref_number, refrence_id, username) do payload = %{ amount: amount_param, device_id: Map.get(params, :device_id), ts: Map.get(params, :ts), username: username, topic: Map.get(params, :topic), status: Map.get(params, :status), error: Map.get(params, :error) } if merchant_ref_number, do: Map.put(payload, :merchant_ref_number, merchant_ref_number), else: payload end defp store_custom_event(event_name, payload) do alias_value = event_name |> String.downcase() |> String.replace(" ", "_") date_added = DateTime.utc_now() # Handle nil username case username = Map.get(payload, :username) created_by_user = if username, do: username, else: "unknown_user" user = if username, do: Repo.get_by(User, email: username), else: nil created_by = if user, do: user.id, else: nil case CustomEvents.get_custom_event_by_alias(alias_value) do nil -> create_new_event(event_name, alias_value, date_added, created_by, created_by_user) existing -> {:ok, existing.id} end end defp create_new_event(event_name, alias_value, date_added, created_by, created_by_user) do attrs = %{ is_published: true, date_added: date_added, created_by: created_by, created_by_user: created_by_user, date_modified: date_added, modified_by: created_by, modified_by_user: created_by_user, name: event_name, alias: alias_value, payloads: %{} } case CustomEvents.create_custom_event(attrs) do {:ok, ce} -> {:ok, ce.id} {:error, _} -> {:error, :creation_failed} end end defp store_custom_event_log(event_id, event_name, payload, merchant_ref_number, refrence_id, transaction_id) do event_value = event_name |> String.downcase() |> String.replace(" ", "_") Logger.info(""" Attempting to store custom event log: Event ID: #{inspect(event_id)} Event Name: #{inspect(event_name)} Event Value: #{inspect(event_value)} Reference ID: #{inspect(refrence_id)} Payload: #{inspect(payload, pretty: true)} """) attrs = %{ transaction_id: transaction_id, event_name: event_name, event_value: event_value, date_added: DateTime.utc_now(), event_id: event_id, payload: payload, refrence_id: refrence_id } Logger.info("Prepared attributes for custom event log: #{inspect(attrs, pretty: true)}") case CustomEventsLog.create_custom_event_log(attrs) do {:ok, log} -> Logger.info("Successfully created custom event log with ID: #{inspect(log.id)}") {:ok, log.id} {:error, changeset} -> Logger.error(""" Failed to create custom event log: Attributes: #{inspect(attrs, pretty: true)} Errors: #{inspect(changeset.errors)} """) {:error, :creation_failed} end rescue error -> Logger.error(""" Unexpected error in store_custom_event_log: Error: #{inspect(error)} Stacktrace: #{inspect(__STACKTRACE__)} Params: event_id: #{inspect(event_id)} event_name: #{inspect(event_name)} refrence_id: #{inspect(refrence_id)} """) {:error, :creation_failed} end end