Add payment confirmation notifications
This commit is contained in:
parent
d3f6db5196
commit
dccad36474
@ -33,7 +33,7 @@ class ContributionsController < ApplicationController
|
||||
[year, @due_members.select {|m| m.expires_on < Date.new(year, 12, 31) }.map { |m|
|
||||
OpenStruct.new(
|
||||
member: m,
|
||||
amount: m.employed? ? 30 : 6,
|
||||
amount: m.employed? ? Config.regular_payment_value : Config.reduced_payment_value,
|
||||
)
|
||||
}]
|
||||
end
|
||||
@ -51,18 +51,15 @@ class ContributionsController < ApplicationController
|
||||
|
||||
# POST /contributions
|
||||
def create
|
||||
@contribution = @member.contributions.build(contribution_params)
|
||||
success = @member.register_contribution(
|
||||
contribution_params,
|
||||
params.dig(:contribution, :overriden_expires_on),
|
||||
params.dig(:contribution, :should_send_notification) == "1")
|
||||
|
||||
Contribution.transaction do
|
||||
if @contribution.save
|
||||
@member.handle_new_contribution(@contribution, params.dig(:contribution, :overriden_expires_on))
|
||||
@member.reset_status!
|
||||
@member.regenerate_notifications
|
||||
|
||||
redirect_to @member, notice: "Contribution was successfully created."
|
||||
else
|
||||
render :new, status: :unprocessable_entity
|
||||
end
|
||||
if success
|
||||
redirect_to @member, notice: "Contribution was successfully created."
|
||||
else
|
||||
render :new, status: :unprocessable_entity
|
||||
end
|
||||
end
|
||||
|
||||
|
@ -29,6 +29,8 @@ class MembersController < ApplicationController
|
||||
|
||||
if @member.save
|
||||
@member.reset_status!
|
||||
NotificationMailer.with(member: @member).registration.deliver_now!
|
||||
|
||||
redirect_to @member, notice: "Member was successfully created."
|
||||
else
|
||||
render :new, status: :unprocessable_entity
|
||||
|
@ -2,4 +2,43 @@ class PaymentsController < ApplicationController
|
||||
def show
|
||||
@payment = Payment.find(params[:id])
|
||||
end
|
||||
|
||||
def callback
|
||||
if ENV["IFTHENPAY_AP_KEY"] != params["key"]
|
||||
render status: 403, json: { error: "invalid anti phishing key" }
|
||||
else
|
||||
member = Member.find_by(number: params["id"].to_i)
|
||||
payment = IfThenPay
|
||||
.payments(params["payment_datetime"])
|
||||
.select { |p| p["Id"] == params["id"] }
|
||||
.first
|
||||
|
||||
if payment.nil?
|
||||
render status: 400, json: { error: "couldn't find payment" }
|
||||
else
|
||||
# TODO: handle double payments
|
||||
contribution_params = {
|
||||
eurocents: payment["Valor"],
|
||||
payment_method: {
|
||||
"MB" => "multibanco",
|
||||
"MBWAY" => "mbway"
|
||||
}.fetch(params["payment_method"]),
|
||||
payment_on: params["payment_datetime"],
|
||||
payment_reference: payment["Terminal"],
|
||||
}
|
||||
|
||||
success = member.register_contribution(
|
||||
contribution_params,
|
||||
nil,
|
||||
true
|
||||
)
|
||||
|
||||
if success
|
||||
render json: { ok: "yes" }
|
||||
else
|
||||
render status: 500, json: { error: "error registering payment" }
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
|
@ -16,4 +16,11 @@ module IfThenPay
|
||||
|
||||
JSON.parse(response.body)
|
||||
end
|
||||
|
||||
def self.payments(date)
|
||||
URI("https://ifthenpay.com/ifmbws/ifmbws.asmx/getPaymentsJson?chavebackoffice=#{ENV['IFTHENPAY_BO_KEY']}&entidade=&subentidade=&dtHrInicio=#{date}&dtHrFim=#{date}&referencia=&valor=&sandbox=0")
|
||||
.then{|u| Net::HTTP.get(u)}
|
||||
.then{|b| Nokogiri::XML(b).child.child.text}
|
||||
.then{|x| JSON.parse(x)}
|
||||
end
|
||||
end
|
||||
|
@ -1,35 +1,55 @@
|
||||
class NotificationMailer < ApplicationMailer
|
||||
before_action :set_notification
|
||||
|
||||
# Subject can be set in your I18n file at config/locales/en.yml
|
||||
# with the following lookup:
|
||||
#
|
||||
# en.notification_mailer.expiration_in_60d.subject
|
||||
#
|
||||
def expiration_in_60d
|
||||
set_notification
|
||||
mail to: @notification.member.email
|
||||
end
|
||||
|
||||
def expiration_in_30d
|
||||
set_notification
|
||||
mail to: @notification.member.email
|
||||
end
|
||||
|
||||
def expired
|
||||
set_notification
|
||||
mail to: @notification.member.email
|
||||
end
|
||||
|
||||
def expired_30d_ago
|
||||
set_notification
|
||||
mail to: @notification.member.email
|
||||
end
|
||||
|
||||
def expired_60d_ago
|
||||
set_notification
|
||||
mail to: @notification.member.email
|
||||
end
|
||||
|
||||
def cancelled
|
||||
set_notification
|
||||
mail to: @notification.member.email
|
||||
end
|
||||
|
||||
def registration
|
||||
@member = params[:member]
|
||||
@payment = @member.create_payment
|
||||
mail to: @member.email
|
||||
end
|
||||
|
||||
def first_payment_confirmation
|
||||
@contribution = params[:contribution]
|
||||
mail to: @contribution.member.email
|
||||
end
|
||||
|
||||
def payment_renewal_confirmation
|
||||
@contribution = params[:contribution]
|
||||
mail to: @contribution.member.email
|
||||
end
|
||||
|
||||
private
|
||||
def set_notification
|
||||
@notification = params[:notification]
|
||||
|
@ -56,6 +56,37 @@ class Member < ApplicationRecord
|
||||
end
|
||||
end
|
||||
|
||||
def register_contribution(contribution_params, overriden_expires_on, should_send_notification)
|
||||
Contribution.transaction do
|
||||
is_first_contribution = self.contributions.empty?
|
||||
|
||||
contribution = self.contributions.build(contribution_params)
|
||||
if contribution.save
|
||||
self.handle_new_contribution(contribution, overriden_expires_on)
|
||||
self.reset_status!
|
||||
self.regenerate_notifications
|
||||
|
||||
if should_send_notification
|
||||
if is_first_contribution
|
||||
NotificationMailer
|
||||
.with(contribution: contribution)
|
||||
.first_payment_confirmation
|
||||
.deliver_now!
|
||||
else
|
||||
NotificationMailer
|
||||
.with(contribution: contribution)
|
||||
.payment_renewal_confirmation
|
||||
.deliver_now!
|
||||
end
|
||||
end
|
||||
|
||||
true
|
||||
else
|
||||
false
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
def handle_new_contribution(contribution, overriden_expires_on)
|
||||
if joined_on.nil?
|
||||
self.joined_on = contribution.payment_on
|
||||
|
@ -28,6 +28,10 @@
|
||||
<td><label for="contribution_payment_reference"><%= t('contributions.attributes.payment_reference') %></label></td>
|
||||
<td><%= form.text_field :payment_reference %></td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td><label for="contribution_should_send_notification"><%= t('contributions.attributes.should_send_notification') %></label></td>
|
||||
<td><%= form.check_box :should_send_notification, checked: true %></td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td colspan=2>
|
||||
<%= t('contributions.new.expires_on_warning') %>
|
||||
|
@ -0,0 +1,60 @@
|
||||
<p><%= t('notification_mailer.greetings', display_name: @contribution.member.display_name) %></p>
|
||||
|
||||
<p>
|
||||
Bem-vinde à ANSOL! Confirmamos que recebemos o teu pagamento, e tua inscrição
|
||||
está válida até <strong><%= @contribution.member.expires_on %></strong>.
|
||||
</p>
|
||||
|
||||
<p>Detalhes do pagamento:</p>
|
||||
<ul>
|
||||
<li><strong>Valor:</strong> <%= @contribution.eurocents %></li>
|
||||
<li><strong>Método:</strong> <%= @contribution.payment_method %></li>
|
||||
<li><strong>Data:</strong> <%= @contribution.payment_on %></li>
|
||||
</ul>
|
||||
|
||||
<p>
|
||||
Vamos inscrever-te na lista de discussão de sócios ansol-socios@ansol.org.
|
||||
Quando o fizermos vais receber um email de confirmação. A maior parte de
|
||||
comunicações que são enviadas são os relatórios trimestrais (disponíveis
|
||||
também no nosso site em https://ansol.org/noticias/), convocatórias para as
|
||||
assembleias gerais, e convites para participar na reunião mensal com a direcção.
|
||||
</p>
|
||||
|
||||
<p>
|
||||
Na primeira quarta feira de todos os meses às 22h a direcção faz uma reunião
|
||||
aberta para que os sócios possam trazer assuntos / fazer perguntas / etc. As
|
||||
reuniões são feitas no nosso Jitsi, em
|
||||
<a href="https://jitsi.ansol.org/ansol-direccao">https://jitsi.ansol.org/ansol-direccao</a>.
|
||||
</p>
|
||||
|
||||
<p>Temos uma sala da comunidade da ANSOL aberta ao público à qual podes aceder:</p>
|
||||
|
||||
<ul>
|
||||
<li>Via Matrix: #geral:ansol.org, ou</li>
|
||||
<li>Via Telegram: https://t.me/ansolgeral</li>
|
||||
</ul>
|
||||
|
||||
<p>
|
||||
Também temos uma sala de Matrix reservada a sócios (#socios:ansol.org).
|
||||
Envia-nos o teu nome de utilizador de Matrix e nós adicionamos-te à sala.
|
||||
Caso não conheças o Matrix, temos uma pequena introdução aqui:
|
||||
<a href="https://gist.github.com/hugopeixoto/128a313ae33109f4b0a55f7242c660f0">
|
||||
https://gist.github.com/hugopeixoto/128a313ae33109f4b0a55f7242c660f0
|
||||
</a>
|
||||
</p>
|
||||
|
||||
<p>Podes seguir as nossas actividades online através de várias plataformas:</p>
|
||||
|
||||
<ul>
|
||||
<li><a href="https://floss.social/@ansol">Mastodon</a></li>
|
||||
<li><a href="https://viste.pt/c/ansol/">Peertube</a></li>
|
||||
<li><a href="https://git.ansol.org/ansol/">Git</a></li>
|
||||
<li><a href="https://twitter.com/ANSOL">Twitter</a></li>
|
||||
</ul>
|
||||
|
||||
<p>
|
||||
Qualquer dúvida em relação às actividades actuais da ANSOL, não hesites em
|
||||
mandar email.
|
||||
</p>
|
||||
|
||||
<%= render partial: "cheers" %>
|
@ -0,0 +1,42 @@
|
||||
<%= t('notification_mailer.greetings', display_name: @contribution.member.display_name) %>
|
||||
|
||||
Bem-vinde à ANSOL! Confirmamos que recebemos o teu pagamento, e tua inscrição
|
||||
está válida até <%= @contribution.member.expires_on %>.
|
||||
|
||||
Detalhes do pagamento:
|
||||
|
||||
* Valor: <%= @contribution.eurocents %>
|
||||
* Método: <%= @contribution.payment_method %>
|
||||
* Data: <%= @contribution.payment_on %>
|
||||
|
||||
Vamos inscrever-te na lista de discussão de sócios ansol-socios@ansol.org.
|
||||
Quando o fizermos vais receber um email de confirmação. A maior parte de
|
||||
comunicações que são enviadas são os relatórios trimestrais (disponíveis
|
||||
também no nosso site em https://ansol.org/noticias/), convocatórias para as
|
||||
assembleias gerais, e convites para participar na reunião mensal com a direcção.
|
||||
|
||||
Na primeira quarta feira de todos os meses às 22h a direcção faz uma reunião
|
||||
aberta para que os sócios possam trazer assuntos / fazer perguntas / etc. As
|
||||
reuniões são feitas no nosso Jitsi, em https://jitsi.ansol.org/ansol-direccao.
|
||||
|
||||
Temos uma sala da comunidade da ANSOL aberta ao público à qual podes aceder:
|
||||
|
||||
* Via Matrix: #geral:ansol.org, ou
|
||||
* Via Telegram: https://t.me/ansolgeral
|
||||
|
||||
Também temos uma sala de Matrix reservada a sócios (#socios:ansol.org).
|
||||
Envia-nos o teu nome de utilizador de Matrix e nós adicionamos-te à sala.
|
||||
Caso não conheças o Matrix, temos uma pequena introdução aqui:
|
||||
https://gist.github.com/hugopeixoto/128a313ae33109f4b0a55f7242c660f0
|
||||
|
||||
Podes seguir as nossas actividades online através de várias plataformas:
|
||||
|
||||
* Mastodon: https://floss.social/@ansol
|
||||
* Peertube: https://viste.pt/c/ansol/
|
||||
* Git: https://git.ansol.org/ansol/
|
||||
* Twitter: https://twitter.com/ANSOL
|
||||
|
||||
Qualquer dúvida em relação às actividades actuais da ANSOL, não hesites em
|
||||
mandar email.
|
||||
|
||||
<%= render partial: "cheers" %>
|
@ -0,0 +1,16 @@
|
||||
<p><%= t('notification_mailer.greetings', display_name: @contribution.member.display_name) %></p>
|
||||
|
||||
<p>
|
||||
Recebemos o teu pagamento. Obrigado por continuares a apoiar a ANSOL. A tua
|
||||
inscrição foi renovada e está válida até
|
||||
<strong><%= @contribution.member.expires_on %></strong>.
|
||||
</p>
|
||||
|
||||
<p>Detalhes do pagamento:</p>
|
||||
<ul>
|
||||
<li><strong>Valor:</strong> <%= @contribution.eurocents %></li>
|
||||
<li><strong>Método:</strong> <%= @contribution.payment_method %></li>
|
||||
<li><strong>Data:</strong> <%= @contribution.payment_on %></li>
|
||||
</ul>
|
||||
|
||||
<%= render partial: "cheers" %>
|
@ -0,0 +1,12 @@
|
||||
<%= t('notification_mailer.greetings', display_name: @contribution.member.display_name) %>
|
||||
|
||||
Recebemos o teu pagamento. Obrigado por continuares a apoiar a ANSOL. A tua
|
||||
inscrição foi renovada e está válida até <%= @contribution.member.expires_on %>.
|
||||
|
||||
Detalhes do pagamento:
|
||||
|
||||
* Valor: <%= @contribution.eurocents %>
|
||||
* Método: <%= @contribution.payment_method %>
|
||||
* Data: <%= @contribution.payment_on %>
|
||||
|
||||
<%= render partial: "cheers" %>
|
22
app/views/notification_mailer/registration.html.erb
Normal file
22
app/views/notification_mailer/registration.html.erb
Normal file
@ -0,0 +1,22 @@
|
||||
<p><%= t('notification_mailer.greetings', display_name: @member.display_name) %></p>
|
||||
|
||||
<p>
|
||||
Obrigado pelo interesse em fazer parte da ANSOL. A tua candidatura foi
|
||||
aprovada pela direcção.
|
||||
</p>
|
||||
|
||||
<p>
|
||||
Para finalizar o teu registo, falta apenas o pagamento da quota anual, no
|
||||
valor de <%= number_with_precision(Config.regular_payment_value, precision: 2) %>€
|
||||
(ou <%= number_with_precision(Config.reduced_payment_value, precision: 2) %>€
|
||||
para pessoas reformadas, desempregadas, ou estudantes).
|
||||
</p>
|
||||
|
||||
<%= render partial: "payment", locals: { payment: @payment } %>
|
||||
|
||||
<p>
|
||||
Depois do pagamento estar confirmado, enviamos-te informações sobre os canais
|
||||
de comunicação da associação, reuniões, etc.
|
||||
</p>
|
||||
|
||||
<%= render partial: "cheers" %>
|
16
app/views/notification_mailer/registration.text.erb
Normal file
16
app/views/notification_mailer/registration.text.erb
Normal file
@ -0,0 +1,16 @@
|
||||
<%= t('notification_mailer.greetings', display_name: @member.display_name) %>
|
||||
|
||||
Obrigado pelo interesse em fazer parte da ANSOL. A tua candidatura foi aprovada
|
||||
pela direcção.
|
||||
|
||||
Para finalizar o teu registo, falta apenas o pagamento da quota anual, no valor
|
||||
de <%= number_with_precision(Config.regular_payment_value, precision: 2) %>€
|
||||
(ou <%= number_with_precision(Config.reduced_payment_value, precision: 2) %>€
|
||||
para pessoas reformadas, desempregadas, ou estudantes).
|
||||
|
||||
<%= render partial: "payment", locals: { payment: @payment } %>
|
||||
|
||||
Depois do pagamento estar confirmado, enviamos-te informações sobre os canais
|
||||
de comunicação da associação, reuniões, etc.
|
||||
|
||||
<%= render partial: "cheers" %>
|
@ -54,6 +54,8 @@ en:
|
||||
student: "Student"
|
||||
retired: "Retired"
|
||||
contributions:
|
||||
attributes:
|
||||
should_send_notification: Send payment receipt
|
||||
due:
|
||||
title: "Due contributions"
|
||||
new:
|
||||
@ -76,5 +78,11 @@ en:
|
||||
subject: "ANSOL - Pagamento de quotas em atraso"
|
||||
expired_60d_ago:
|
||||
subject: "ANSOL - Suspensão de inscrição iminente"
|
||||
first_payment_confirmation:
|
||||
subject: "ANSOL - Payment received: Welcome!"
|
||||
payment_renewal_confirmation:
|
||||
subject: "ANSOL - Payment received"
|
||||
registration:
|
||||
subject: "ANSOL - Registration approved: Payment required"
|
||||
cancelled:
|
||||
subject: "ANSOL - Inscrição cancelada"
|
||||
|
@ -85,6 +85,7 @@ pt:
|
||||
payment_on: Data de pagamento
|
||||
payment_method: Método de pagamento
|
||||
payment_reference: Referência
|
||||
should_send_notification: Enviar comprovativo de pagamento
|
||||
edit:
|
||||
member: "Membro"
|
||||
title: "Editar dados de contribuição"
|
||||
@ -113,6 +114,12 @@ pt:
|
||||
subject: "ANSOL - Pagamento de quotas em atraso"
|
||||
expired_60d_ago:
|
||||
subject: "ANSOL - Suspensão de inscrição iminente"
|
||||
first_payment_confirmation:
|
||||
subject: "ANSOL - Pagamento recebido: Mensagem de boas vindas"
|
||||
payment_renewal_confirmation:
|
||||
subject: "ANSOL - Pagamento de quotas recebido"
|
||||
registration:
|
||||
subject: "ANSOL - Inscrição aprovada: Pagamento inicial de quotas"
|
||||
cancelled:
|
||||
subject: "ANSOL - Inscrição cancelada"
|
||||
greetings: "Car(a/o/e) %{display_name}"
|
||||
|
@ -32,7 +32,11 @@ Rails.application.routes.draw do
|
||||
resource :board, only: [:edit, :update]
|
||||
resource :letters, only: [:create]
|
||||
|
||||
resources :payments, only: [:show]
|
||||
resources :payments, only: [:show] do
|
||||
collection do
|
||||
get :callback
|
||||
end
|
||||
end
|
||||
|
||||
resource :initial_setup, only: [:create, :show]
|
||||
end
|
||||
|
@ -8,6 +8,8 @@ SMTP_FROM_NAME=Example Name
|
||||
|
||||
IFTHENPAY_KEY=XXXX-XXXXXX
|
||||
IFTHENPAY_ACCOUNTS=MBWAY|XXX-XXXXXX;XXXXX|XXX
|
||||
IFTHENPAY_BO_KEY=XXXX-XXXX-XXXX-XXXX
|
||||
IFTHENPAY_AP_KEY=my_anti_phishing_key
|
||||
|
||||
BASE_HOST=example.org
|
||||
RAILS_LOG_TO_STDOUT=true
|
||||
|
Loading…
Reference in New Issue
Block a user