All checks were successful
Build and Publish / build-release (push) Successful in 4m46s
216 lines
6.4 KiB
Elixir
216 lines
6.4 KiB
Elixir
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 ProviderService.S3
|
|
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: "Upload solicitation template",
|
|
description: "Upload a fillable PDF. Fields are auto-discovered via solicitation_service.",
|
|
parameters: [
|
|
provider_id: [in: :path, type: :string, required: true]
|
|
],
|
|
request_body:
|
|
{"Multipart PDF upload", "multipart/form-data", PS.UploadTemplateRequest, required: true},
|
|
responses: [
|
|
created: {"Template registered", "application/json", PS.UploadTemplateResponse}
|
|
]
|
|
)
|
|
|
|
def upload_template(conn, %{"provider_id" => provider_id} = params) do
|
|
# %Plug.Upload{}
|
|
upload = params["file"]
|
|
policy_type = params["policy_type"]
|
|
client_type = params["client_type"]
|
|
|
|
template_id = Ecto.UUID.generate()
|
|
s3_key = "templates/#{provider_id}/#{policy_type}/#{client_type}/#{template_id}.pdf"
|
|
|
|
# Upload to S3/MinIO
|
|
case S3.upload(upload.path, s3_key) do
|
|
:ok ->
|
|
# Discover AcroForm fields via solicitation_service
|
|
fields = discover_fields(s3_key)
|
|
|
|
cmd = %AddProviderTemplate{
|
|
provider_id: provider_id,
|
|
template_id: template_id,
|
|
client_type: client_type,
|
|
policy_type: policy_type,
|
|
s3_key: s3_key,
|
|
fields: fields
|
|
}
|
|
|
|
case ProviderService.CommandedApp.dispatch(cmd) do
|
|
:ok ->
|
|
conn
|
|
|> put_status(:created)
|
|
|> json(%{template_id: template_id, s3_key: s3_key, fields: fields})
|
|
|
|
{:error, reason} ->
|
|
conn |> put_status(:unprocessable_entity) |> json(%{error: reason})
|
|
end
|
|
|
|
{:error, reason} ->
|
|
conn
|
|
|> put_status(:internal_server_error)
|
|
|> json(%{error: "S3 upload failed: #{reason}"})
|
|
end
|
|
end
|
|
|
|
defp discover_fields(s3_key) do
|
|
url = Application.get_env(:provider_service, :solicitation_service_url)
|
|
|
|
case Req.get("#{url}/api/solicitations/templates/fields", params: [s3_key: s3_key]) do
|
|
{:ok, %{status: 200, body: %{"fields" => fields}}} -> fields
|
|
_ -> []
|
|
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
|