defmodule ProviderServiceWeb.TemplateController do use ProviderServiceWeb, :controller use OpenApiSpex.ControllerSpecs alias ProviderService.CommandedApp alias ProviderService.Queries.ProviderQueries alias ProviderService.Commands.{ AddProviderTemplate, ActivateProviderTemplate, DeactivateProviderTemplate, SetDefaultProviderTemplate, RemoveProviderTemplate } alias ProviderServiceWeb.Schemas.Provider, as: PS operation(:index, summary: "List templates for provider", parameters: [ provider_id: [in: :path, type: :string, required: true] ], responses: [ ok: {"Templates", "application/json", %OpenApiSpex.Schema{type: :object}} ] ) def index(conn, %{"provider_id" => provider_id}) do case ProviderQueries.get_provider(provider_id) do {:ok, provider} -> conn |> put_status(:ok) |> json(%{data: provider.templates}) {:error, :not_found} -> conn |> put_status(:not_found) |> json(%{error: "provider not found"}) end end operation(:upload_template, summary: "Register template by document URL", description: "Register a template document URL for a provider.", parameters: [ provider_id: [in: :path, type: :string, required: true] ], request_body: {"Document URL payload", "application/json", PS.UploadTemplateRequest, required: true}, responses: [ created: {"Template registered", "application/json", PS.UploadTemplateResponse} ] ) def upload_template(conn, %{"provider_id" => provider_id} = params) do document_url = params["document_url"] policy_type = params["policy_type"] client_type = params["client_type"] template_id = Ecto.UUID.generate() cmd = %AddProviderTemplate{ provider_id: provider_id, template_id: template_id, client_type: client_type, policy_type: policy_type, document_url: document_url } case ProviderService.CommandedApp.dispatch(cmd) do :ok -> conn |> put_status(:created) |> json(%{template_id: template_id, document_url: document_url}) {:error, reason} -> conn |> put_status(:unprocessable_entity) |> json(%{error: reason}) end end operation(:activate, summary: "Activate a template", parameters: [ provider_id: [in: :path, type: :string, required: true], template_id: [in: :path, type: :string, required: true] ], responses: [ ok: {"Template activated", "application/json", PS.ProviderResponse} ] ) def activate(conn, %{"provider_id" => provider_id, "template_id" => template_id} = params) do command = %ActivateProviderTemplate{ provider_id: provider_id, template_id: template_id, policy_type: params["policy_type"], client_type: params["client_type"] } dispatch_and_respond(conn, command, provider_id) end operation(:deactivate, summary: "Deactivate a template", parameters: [ provider_id: [in: :path, type: :string, required: true], template_id: [in: :path, type: :string, required: true] ], responses: [ ok: {"Template deactivated", "application/json", PS.ProviderResponse} ] ) def deactivate(conn, %{"provider_id" => provider_id, "template_id" => template_id} = params) do command = %DeactivateProviderTemplate{ provider_id: provider_id, template_id: template_id, policy_type: params["policy_type"], client_type: params["client_type"] } dispatch_and_respond(conn, command, provider_id) end operation(:set_default, summary: "Set default template for a policy type", parameters: [ provider_id: [in: :path, type: :string, required: true], template_id: [in: :path, type: :string, required: true] ], responses: [ ok: {"Default template set", "application/json", PS.ProviderResponse} ] ) def set_default(conn, %{"provider_id" => provider_id, "template_id" => template_id} = params) do command = %SetDefaultProviderTemplate{ provider_id: provider_id, template_id: template_id, policy_type: params["policy_type"], client_type: params["client_type"] } dispatch_and_respond(conn, command, provider_id) end operation(:remove, summary: "Remove a template", parameters: [ provider_id: [in: :path, type: :string, required: true], template_id: [in: :path, type: :string, required: true] ], responses: [ ok: {"Template removed", "application/json", PS.ProviderResponse} ] ) def remove(conn, %{"provider_id" => provider_id, "template_id" => template_id} = params) do command = %RemoveProviderTemplate{ provider_id: provider_id, template_id: template_id, policy_type: params["policy_type"], client_type: params["client_type"] } dispatch_and_respond(conn, command, provider_id) end defp dispatch_and_respond(conn, command, provider_id) do case CommandedApp.dispatch(command, consistency: :strong) do :ok -> {:ok, provider} = ProviderQueries.get_provider(provider_id) conn |> put_status(:ok) |> json(%{data: provider_json(provider)}) {:error, reason} -> conn |> put_status(:unprocessable_entity) |> json(%{error: inspect(reason)}) end end defp provider_json(p) do %{ provider_id: p.provider_id, name: p.name, email: p.email, phone: p.phone, contact_name: p.contact_name, ruc: p.ruc, address: p.address, active: p.active, templates: p.templates, default_templates: p.default_templates } end end