lib/code_corps/emails/receipt_email.ex
defmodule CodeCorps.Emails.ReceiptEmail do
import Bamboo.Email, only: [to: 2]
import Bamboo.PostmarkHelper
alias CodeCorps.Emails.BaseEmail
alias CodeCorps.{DonationGoal, Project, Repo, StripeConnectCharge, StripeConnectSubscription, WebClient}
@spec create(StripeConnectCharge.t, Stripe.Invoice.t) :: Bamboo.Email.t
def create(%StripeConnectCharge{} = charge, %Stripe.Invoice{} = invoice) do
with %StripeConnectCharge{} = charge <- Repo.preload(charge, :user),
%Project{} = project <- get_project(invoice.subscription),
{:ok, %DonationGoal{} = current_donation_goal} <- get_current_donation_goal(project),
template_model <- build_model(charge, project, current_donation_goal)
do
BaseEmail.create
|> to(charge.user.email)
|> template(template_id(), template_model)
else
nil -> {:error, :project_not_found}
other -> other
end
end
@spec get_project(String.t) :: Project.t | {:error, :subscription_not_found}
defp get_project(subscription_id_from_stripe) do
with %StripeConnectSubscription{} = subscription <- get_subscription(subscription_id_from_stripe) do
subscription.stripe_connect_plan.project
else
nil -> {:error, :subscription_not_found}
end
end
@spec get_subscription(String.t) :: StripeConnectSubscription.t | nil
defp get_subscription(subscription_id_from_stripe) do
StripeConnectSubscription
|> Repo.get_by(id_from_stripe: subscription_id_from_stripe)
|> Repo.preload(stripe_connect_plan: [project: :organization])
end
@spec get_current_donation_goal(Project.t) :: DonationGoal.t | {:error, :donation_goal_not_found}
defp get_current_donation_goal(project) do
case Repo.get_by(DonationGoal, current: true, project_id: project.id) do
nil -> {:error, :donation_goal_not_found}
donation_goal -> {:ok, donation_goal}
end
end
@spec build_model(StripeConnectCharge.t, Project.t, DonationGoal.t) :: map
defp build_model(charge, project, current_donation_goal) do
%{
charge_amount: charge.amount |> format_amount(),
charge_statement_descriptor: charge.statement_descriptor,
high_five_image_url: high_five_image_url(),
name: BaseEmail.get_name(charge.user),
project_current_donation_goal_description: current_donation_goal.description,
project_title: project.title,
project_url: project |> url(),
subject: project |> build_subject_line()
}
end
@spec build_subject_line(Project.t) :: String.t
defp build_subject_line(project) do
"Your monthly donation to " <> project.title
end
@spec high_five_image_url :: String.t
defp high_five_image_url, do: Enum.random(high_five_image_urls())
@spec high_five_image_urls :: list(String.t)
defp high_five_image_urls, do: [
"https://d3pgew4wbk2vb1.cloudfront.net/emails/images/emoji-1f64c-1f3fb@2x.png",
"https://d3pgew4wbk2vb1.cloudfront.net/emails/images/emoji-1f64c-1f3fc@2x.png",
"https://d3pgew4wbk2vb1.cloudfront.net/emails/images/emoji-1f64c-1f3fd@2x.png",
"https://d3pgew4wbk2vb1.cloudfront.net/emails/images/emoji-1f64c-1f3fe@2x.png",
"https://d3pgew4wbk2vb1.cloudfront.net/emails/images/emoji-1f64c-1f3ff@2x.png"
]
@spec format_amount(integer) :: binary
defp format_amount(amount) do
amount |> Money.new(:USD) |> Money.to_string()
end
@spec url(Project.t) :: String.t
defp url(project) do
WebClient.url()
|> URI.merge(project.organization.slug <> "/" <> project.slug)
|> URI.to_string
end
@spec template_id :: String.t
defp template_id, do: Application.get_env(:code_corps, :postmark_receipt_template)
end