From 9058ed98f7cbbe82d231bf7085a15ad7c76391a6 Mon Sep 17 00:00:00 2001 From: Hugo Peixoto Date: Wed, 12 Jul 2023 19:13:08 +0100 Subject: [PATCH] Adds payment page Instead of sending all the payment details by email, we're now sending only a link to a page on this platform. This is to help reduce questions of whether the emails are from scammers or real. --- README.md | 6 +- app/assets/images/logo.svg | 38 ++++++++++++ app/assets/stylesheets/application.css | 32 +++++++++- app/controllers/boards_controller.rb | 2 +- app/controllers/payments_controller.rb | 5 ++ app/lib/config.rb | 34 +++++++++++ app/mailers/notification_mailer.rb | 2 +- app/models/member.rb | 19 ++++-- app/models/payment.rb | 3 + app/views/layouts/application.html.erb | 16 ++++- .../notification_mailer/_cheers.html.erb | 4 ++ .../notification_mailer/_cheers.text.erb | 2 + .../notification_mailer/_payment.html.erb | 22 ++----- .../notification_mailer/_payment.text.erb | 15 +---- .../expiration_in_30d.html.erb | 7 +-- .../expiration_in_30d.text.erb | 5 +- .../expiration_in_60d.html.erb | 7 +-- .../expiration_in_60d.text.erb | 5 +- .../notification_mailer/expired.html.erb | 7 +-- .../notification_mailer/expired.text.erb | 5 +- .../expired_30d_ago.html.erb | 7 +-- .../expired_30d_ago.text.erb | 5 +- .../expired_60d_ago.html.erb | 7 +-- .../expired_60d_ago.text.erb | 5 +- app/views/payments/show.html.erb | 60 +++++++++++++++++++ config/locales/en.yml | 4 ++ config/locales/pt.yml | 4 ++ config/routes.rb | 2 + db/migrate/20230712103042_create_payments.rb | 11 ++++ db/schema.rb | 11 +++- lib/tasks/saucy.rake | 2 +- 31 files changed, 271 insertions(+), 83 deletions(-) create mode 100644 app/assets/images/logo.svg create mode 100644 app/controllers/payments_controller.rb create mode 100644 app/lib/config.rb create mode 100644 app/models/payment.rb create mode 100644 app/views/notification_mailer/_cheers.html.erb create mode 100644 app/views/notification_mailer/_cheers.text.erb create mode 100644 app/views/payments/show.html.erb create mode 100644 db/migrate/20230712103042_create_payments.rb diff --git a/README.md b/README.md index 95beff5..4bf4c65 100644 --- a/README.md +++ b/README.md @@ -96,6 +96,10 @@ Para o projecto funcionar a 100%, precisa de algumas dependências externas: Todas estas coisas são configuráveis via variáveis de ambiente. A lista de variáveis está disponível no ficheiro `env.example`. +**NOTA**: o projecto ainda não está pronto para ser personalizado à imagem de +outras associações, estando o contexto da ANSOL codificado em vários pontos da +aplicação. Alguns destes detalhes podem ser definidos em `app/lib/config.rb`. + ## Pôr isto a dar @@ -113,6 +117,6 @@ Quando se acede à plataforma pela primeira vez, é-nos pedido um endereço de email para criar a primeira conta de administração. Este endereço precisa de conseguir receber mensagens para o processo de recuperação de senha funcionar. -Depois deste processo terminado, é possível gerir até 5 contas de +Depois deste processo terminado, é possível gerir até 6 contas de administração. Atenção que qualquer uma delas consegue apagar as restantes (e até a si própria). diff --git a/app/assets/images/logo.svg b/app/assets/images/logo.svg new file mode 100644 index 0000000..8de1c96 --- /dev/null +++ b/app/assets/images/logo.svg @@ -0,0 +1,38 @@ + + + + + + + image/svg+xml + + + + + + + + + + + diff --git a/app/assets/stylesheets/application.css b/app/assets/stylesheets/application.css index 3305272..a5418a4 100644 --- a/app/assets/stylesheets/application.css +++ b/app/assets/stylesheets/application.css @@ -1,10 +1,38 @@ /* Application styles */ body { - max-width: 1000px; - margin: 0 auto; + margin: 0px; } +main, nav, footer { + margin: 0 auto; + max-width: 1000px; +} + +main { + padding: 10px; +} + +.banner { + width: 100%; + height: 30px; + padding: 15px; + background-image: url(logo.svg); + background-size: auto 30px; + background-repeat: no-repeat; + background-position: center; + background-color: #041952; +} + +footer { + border-top: 1px solid #aaa; + margin-top: 20px; + padding: 20px 10px; +} + +footer div + div { margin-top: 10px; } + + table { border: 1px solid black; border-collapse: collapse; diff --git a/app/controllers/boards_controller.rb b/app/controllers/boards_controller.rb index 564557d..9b5caf2 100644 --- a/app/controllers/boards_controller.rb +++ b/app/controllers/boards_controller.rb @@ -3,7 +3,7 @@ class BoardsController < ApplicationController def edit @users = User.where(active: true) - @users += Array.new(5 - @users.size) { User.new } + @users += Array.new(6 - @users.size) { User.new } end def update diff --git a/app/controllers/payments_controller.rb b/app/controllers/payments_controller.rb new file mode 100644 index 0000000..d55aac1 --- /dev/null +++ b/app/controllers/payments_controller.rb @@ -0,0 +1,5 @@ +class PaymentsController < ApplicationController + def show + @payment = Payment.find(params[:id]) + end +end diff --git a/app/lib/config.rb b/app/lib/config.rb new file mode 100644 index 0000000..975f53e --- /dev/null +++ b/app/lib/config.rb @@ -0,0 +1,34 @@ +module Config + def self.organization_full_name + "ANSOL - Associação Nacional para o Software Livre" + end + + def self.organization_website + "https://ansol.org" + end + + def self.regular_payment_value + 30 + end + + def self.reduced_payment_value + 6 + end + + def self.ifthenpay_payment_title + "Quotas ANSOL" + end + + def self.payment_iban + "PT50 0035 2178 00027478430 14" + end + + def self.payment_proof_email + "direccao@ansol.org" + end + + def self.reduced_payment_description + "Caso queiras usufruir da quota reduzida de 6.00€ para estudantes, pessoas + desempregadas ou reformadas, envia-nos um comprovativo desse estatuto." + end +end diff --git a/app/mailers/notification_mailer.rb b/app/mailers/notification_mailer.rb index b9f355b..64ba322 100644 --- a/app/mailers/notification_mailer.rb +++ b/app/mailers/notification_mailer.rb @@ -33,6 +33,6 @@ class NotificationMailer < ApplicationMailer private def set_notification @notification = params[:notification] - @link = @notification.member.regular_ifthenpay_link + @payment = @notification.member.create_payment end end diff --git a/app/models/member.rb b/app/models/member.rb index 3488915..c6e7e7c 100644 --- a/app/models/member.rb +++ b/app/models/member.rb @@ -2,16 +2,25 @@ class Member < ApplicationRecord default_scope { where(excluded: false) } has_many :contributions has_many :notifications + has_many :payments has_paper_trail def self.ransackable_attributes(auth_object = nil) %w[display_name legal_name email identification_number] end + def create_payment + payments.create(status: "pending") + end + def cancelled_on expires_on + 90.days end + def obtains_full_rights_on + joined_on + 6.months + end + def reset_status! update(status: expected_status) end @@ -36,7 +45,7 @@ class Member < ApplicationRecord def expected_status if joined_on.nil? :pending - elsif (joined_on + 6.months).future? + elsif obtains_full_rights_on.future? :passive elsif expires_on.future? :active @@ -82,14 +91,14 @@ class Member < ApplicationRecord def generate_missing_ifthenpay_links! self.regular_ifthenpay_link = IfThenPay.generate_gateway_link( id: number, - amount: "30.00", - description: "Quotas ANSOL", + amount: "%.2f" % Config.regular_payment_value, + description: Config.ifthenpay_payment_title, ) unless self.regular_ifthenpay_link.present? self.reduced_ifthenpay_link = IfThenPay.generate_gateway_link( id: number, - amount: "6.00", - description: "Quotas ANSOL", + amount: "%.2f" % Config.reduced_payment_value, + description: Config.ifthenpay_payment_title, ) unless self.reduced_ifthenpay_link.present? save! diff --git a/app/models/payment.rb b/app/models/payment.rb new file mode 100644 index 0000000..6514060 --- /dev/null +++ b/app/models/payment.rb @@ -0,0 +1,3 @@ +class Payment < ApplicationRecord + belongs_to :member +end diff --git a/app/views/layouts/application.html.erb b/app/views/layouts/application.html.erb index 26a489e..6931a1f 100644 --- a/app/views/layouts/application.html.erb +++ b/app/views/layouts/application.html.erb @@ -11,6 +11,7 @@ + <% if signed_in? %> <% end %> - <%= yield %> +
+ <%= yield %> +
+ + diff --git a/app/views/notification_mailer/_cheers.html.erb b/app/views/notification_mailer/_cheers.html.erb new file mode 100644 index 0000000..8672089 --- /dev/null +++ b/app/views/notification_mailer/_cheers.html.erb @@ -0,0 +1,4 @@ +

+ Saudações livres,
+ Direcção da ANSOL +

diff --git a/app/views/notification_mailer/_cheers.text.erb b/app/views/notification_mailer/_cheers.text.erb new file mode 100644 index 0000000..33f2f24 --- /dev/null +++ b/app/views/notification_mailer/_cheers.text.erb @@ -0,0 +1,2 @@ +Saudações livres, +Direcção da ANSOL diff --git a/app/views/notification_mailer/_payment.html.erb b/app/views/notification_mailer/_payment.html.erb index 0f04c9a..1b4a855 100644 --- a/app/views/notification_mailer/_payment.html.erb +++ b/app/views/notification_mailer/_payment.html.erb @@ -3,20 +3,8 @@ MBWAY:

- - -

- Caso queiras usufruir da quota reduzida de 6.00€ para estudantes, pessoas - desempregadas ou reformadas, pedimos que nos envies um comprovativo desse - estatuto e faças o pagamento por transferência bancária. -

- -

- Se optares pelo método de transferência bancária, pedimos que envies o - comprovativo de transferência em resposta a este email ou para o endereço - direccao@ansol.org. -

+
+ + <%= t('notification_mailer.payment_cta') %> + +
diff --git a/app/views/notification_mailer/_payment.text.erb b/app/views/notification_mailer/_payment.text.erb index 7aee751..4b9b8ba 100644 --- a/app/views/notification_mailer/_payment.text.erb +++ b/app/views/notification_mailer/_payment.text.erb @@ -1,14 +1,3 @@ -Aceitamos pagamento via transferência bancária, referência multibanco ou -MBWAY: +Aceitamos pagamento via transferência bancária, referência multibanco ou MBWAY: -* Valor: 30.00€ -* Transferência bancária: PT50 0035 2178 00027478430 14 -* Multibanco ou MBWAY: <%= @link %> - -Caso queiras usufruir da quota reduzida de 6.00€ para estudantes, pessoas -desempregadas e reformadas, pedimos que nos envies um comprovativo desse -estatuto e faças o pagamento por transferência bancária. - -Se optares pelo método de transferência bancária, pedimos que envies o -comprovativo de transferência em resposta a este email ou para o endereço -direccao@ansol.org. +<%= payment_url(payment) %> diff --git a/app/views/notification_mailer/expiration_in_30d.html.erb b/app/views/notification_mailer/expiration_in_30d.html.erb index 64186d9..c90df47 100644 --- a/app/views/notification_mailer/expiration_in_30d.html.erb +++ b/app/views/notification_mailer/expiration_in_30d.html.erb @@ -16,9 +16,6 @@ das quotas até <%= @notification.member.expires_on %>.

-<%= render partial: "payment", locals: { ifthenpay: @link } %> +<%= render partial: "payment", locals: { payment: @payment } %> -

- Saudações livres,
- Direcção da ANSOL -

+<%= render partial: "cheers" %> diff --git a/app/views/notification_mailer/expiration_in_30d.text.erb b/app/views/notification_mailer/expiration_in_30d.text.erb index c02fae4..023831b 100644 --- a/app/views/notification_mailer/expiration_in_30d.text.erb +++ b/app/views/notification_mailer/expiration_in_30d.text.erb @@ -10,7 +10,6 @@ participação. Para estender a tua inscrição por mais um ano, pedimos que faças o pagamento das quotas até <%= @notification.member.expires_on %>. -<%= render partial: "payment", locals: { ifthenpay: @link } %> +<%= render partial: "payment", locals: { payment: @payment } %> -Saudações livres, -Direcção da ANSOL +<%= render partial: "cheers" %> diff --git a/app/views/notification_mailer/expiration_in_60d.html.erb b/app/views/notification_mailer/expiration_in_60d.html.erb index fe15d50..aa1c241 100644 --- a/app/views/notification_mailer/expiration_in_60d.html.erb +++ b/app/views/notification_mailer/expiration_in_60d.html.erb @@ -16,9 +16,6 @@ das quotas até <%= @notification.member.expires_on %>.

-<%= render partial: "payment", locals: { ifthenpay: @link } %> +<%= render partial: "payment", locals: { payment: @payment } %> -

- Saudações livres,
- Direcção da ANSOL -

+<%= render partial: "cheers" %> diff --git a/app/views/notification_mailer/expiration_in_60d.text.erb b/app/views/notification_mailer/expiration_in_60d.text.erb index 28b31bf..7cf2950 100644 --- a/app/views/notification_mailer/expiration_in_60d.text.erb +++ b/app/views/notification_mailer/expiration_in_60d.text.erb @@ -10,7 +10,6 @@ participação. Para estender a tua inscrição por mais um ano, pedimos que faças o pagamento das quotas até <%= @notification.member.expires_on %>. -<%= render partial: "payment", locals: { ifthenpay: @link } %> +<%= render partial: "payment", locals: { payment: @payment } %> -Saudações livres, -Direcção da ANSOL +<%= render partial: "cheers" %> diff --git a/app/views/notification_mailer/expired.html.erb b/app/views/notification_mailer/expired.html.erb index fc12b72..170944b 100644 --- a/app/views/notification_mailer/expired.html.erb +++ b/app/views/notification_mailer/expired.html.erb @@ -12,7 +12,7 @@ nossas actividades. Gostaríamos de continuar a contar com a tua participação.

-<%= render partial: "payment", locals: { ifthenpay: @link } %> +<%= render partial: "payment", locals: { payment: @payment } %>

Caso não recebamos o pagamento até dia <%= @notification.member.cancelled_on @@ -20,7 +20,4 @@ esclarecer qualquer dúvida através do endereço direccao@ansol.org.

-

- Saudações livres,
- Direcção da ANSOL -

+<%= render partial: "cheers" %> diff --git a/app/views/notification_mailer/expired.text.erb b/app/views/notification_mailer/expired.text.erb index bb6dc31..a3c9918 100644 --- a/app/views/notification_mailer/expired.text.erb +++ b/app/views/notification_mailer/expired.text.erb @@ -6,11 +6,10 @@ contribuição anual. Dependemos exclusivamente da contribuição dos nossos membros para suportar as nossas actividades. Gostaríamos de continuar a contar com a tua participação. -<%= render partial: "payment", locals: { ifthenpay: @link } %> +<%= render partial: "payment", locals: { payment: @payment } %> Caso não recebamos o pagamento até dia <%= @notification.member.cancelled_on %>, cancelaremos permanentemente a tua inscrição. Estamos disponíveis para esclarecer qualquer dúvida através do endereço direccao@ansol.org. -Saudações livres, -Direcção da ANSOL +<%= render partial: "cheers" %> diff --git a/app/views/notification_mailer/expired_30d_ago.html.erb b/app/views/notification_mailer/expired_30d_ago.html.erb index 8638673..5d72f6e 100644 --- a/app/views/notification_mailer/expired_30d_ago.html.erb +++ b/app/views/notification_mailer/expired_30d_ago.html.erb @@ -12,7 +12,7 @@ nossas actividades. Gostaríamos de continuar a contar com a tua participação.

-<%= render partial: "payment", locals: { ifthenpay: @link } %> +<%= render partial: "payment", locals: { payment: @payment } %>

Caso não recebamos o pagamento até dia <%= @notification.member.cancelled_on @@ -20,7 +20,4 @@ esclarecer qualquer dúvida através do endereço direccao@ansol.org.

-

- Saudações livres, - Direcção da ANSOL -

+<%= render partial: "cheers" %> diff --git a/app/views/notification_mailer/expired_30d_ago.text.erb b/app/views/notification_mailer/expired_30d_ago.text.erb index 516075a..0290493 100644 --- a/app/views/notification_mailer/expired_30d_ago.text.erb +++ b/app/views/notification_mailer/expired_30d_ago.text.erb @@ -6,11 +6,10 @@ a tua contribuição anual. Dependemos exclusivamente da contribuição dos nossos membros para suportar as nossas actividades. Gostaríamos de continuar a contar com a tua participação. -<%= render partial: "payment", locals: { ifthenpay: @link } %> +<%= render partial: "payment", locals: { payment: @payment } %> Caso não recebamos o pagamento até dia <%= @notification.member.cancelled_on %>, cancelaremos permanentemente a tua inscrição. Estamos disponíveis para esclarecer qualquer dúvida através do endereço direccao@ansol.org. -Saudações livres, -Direcção da ANSOL +<%= render partial: "cheers" %> diff --git a/app/views/notification_mailer/expired_60d_ago.html.erb b/app/views/notification_mailer/expired_60d_ago.html.erb index fc12b72..170944b 100644 --- a/app/views/notification_mailer/expired_60d_ago.html.erb +++ b/app/views/notification_mailer/expired_60d_ago.html.erb @@ -12,7 +12,7 @@ nossas actividades. Gostaríamos de continuar a contar com a tua participação.

-<%= render partial: "payment", locals: { ifthenpay: @link } %> +<%= render partial: "payment", locals: { payment: @payment } %>

Caso não recebamos o pagamento até dia <%= @notification.member.cancelled_on @@ -20,7 +20,4 @@ esclarecer qualquer dúvida através do endereço direccao@ansol.org.

-

- Saudações livres,
- Direcção da ANSOL -

+<%= render partial: "cheers" %> diff --git a/app/views/notification_mailer/expired_60d_ago.text.erb b/app/views/notification_mailer/expired_60d_ago.text.erb index 293d58f..347610b 100644 --- a/app/views/notification_mailer/expired_60d_ago.text.erb +++ b/app/views/notification_mailer/expired_60d_ago.text.erb @@ -6,11 +6,10 @@ a tua contribuição anual. Dependemos exclusivamente da contribuição dos nossos membros para suportar as nossas actividades. Gostaríamos de continuar a contar com a tua participação. -<%= render partial: "payment", locals: { ifthenpay: @link } %> +<%= render partial: "payment", locals: { payment: @payment } %> Caso não recebamos o pagamento até dia <%= @notification.member.cancelled_on %>, cancelaremos permanentemente a tua inscrição. Estamos disponíveis para esclarecer qualquer dúvida através do endereço direccao@ansol.org. -Saudações livres, -Direcção da ANSOL +<%= render partial: "cheers" %> diff --git a/app/views/payments/show.html.erb b/app/views/payments/show.html.erb new file mode 100644 index 0000000..19fe47b --- /dev/null +++ b/app/views/payments/show.html.erb @@ -0,0 +1,60 @@ +

Pagamento de quotas

+ +

+ Olá <%= @payment.member.display_name %>. + Para estender a tua inscrição por + mais um ano, pedimos que faças o pagamento das quotas até + <%= @payment.member.expires_on %>. +

+ +

<%= Config.reduced_payment_description %>

+ +

Aceitamos pagamento via transferência bancária, referência multibanco ou MBWAY.

+ +
+ + +
+

Valor: <%= number_with_precision(Config.regular_payment_value, precision: 2) %>€

+ +

<%= link_to "Pagar por Multibanco ou MBWAY", @payment.member.regular_ifthenpay_link, class: 'button' %>

+

Pagar por transferência bancária:

+
    +
  • IBAN: <%= Config.payment_iban %>
  • +
  • obrigatório enviar comprovativo de pagamento para <%= Config.payment_proof_email %>
  • +
+
+
+ +
+ + +
+

Valor: <%= number_with_precision(Config.reduced_payment_value, precision: 2) %>€

+ +

<%= link_to "Pagar por Multibanco ou MBWAY", @payment.member.reduced_ifthenpay_link, class: 'button' %>

+

Pagar por transferência bancária:

+
    +
  • IBAN: <%= Config.payment_iban %>
  • +
  • obrigatório enviar comprovativo de pagamento para <%= Config.payment_proof_email %>
  • +
+
+
+ + diff --git a/config/locales/en.yml b/config/locales/en.yml index 8d447ba..523f6aa 100644 --- a/config/locales/en.yml +++ b/config/locales/en.yml @@ -5,6 +5,9 @@ en: notifications: "Notificações" contributions: "Contributions" due_contributions: "Dues" + footer: + description: saucy – Membership management platform. + free_software_html: It's Free Software. members: index: title: "Members" @@ -61,6 +64,7 @@ en: year after that. You can override the expiration date by setting a date below. notification_mailer: + payment_cta: "Pay now" expiration_in_60d: subject: "ANSOL - Pagamento anual de quotas" title: "Pagamento anual de quotas" diff --git a/config/locales/pt.yml b/config/locales/pt.yml index 74aad33..da8a1f4 100644 --- a/config/locales/pt.yml +++ b/config/locales/pt.yml @@ -8,6 +8,9 @@ pt: notifications: "Notificações" contributions: "Contribuições" due_contributions: "Dívidas" + footer: + description: saucy – Plataforma de gestão de sócios. + free_software_html: É Software Livre. members: delete: confirmation_message: | @@ -99,6 +102,7 @@ pt: due: title: "Contribuições em dívida" notification_mailer: + payment_cta: "Pagar quotas" expiration_in_60d: subject: "ANSOL - Pagamento anual de quotas" expiration_in_30d: diff --git a/config/routes.rb b/config/routes.rb index 685b714..647ca8c 100644 --- a/config/routes.rb +++ b/config/routes.rb @@ -32,5 +32,7 @@ Rails.application.routes.draw do resource :board, only: [:edit, :update] resource :letters, only: [:create] + resources :payments, only: [:show] + resource :initial_setup, only: [:create, :show] end diff --git a/db/migrate/20230712103042_create_payments.rb b/db/migrate/20230712103042_create_payments.rb new file mode 100644 index 0000000..ef076bb --- /dev/null +++ b/db/migrate/20230712103042_create_payments.rb @@ -0,0 +1,11 @@ +class CreatePayments < ActiveRecord::Migration[7.0] + def change + create_table :payments, id: :uuid do |t| + t.references :member, type: :uuid, foreign_key: true, null: false + + t.string :status + + t.timestamps + end + end +end diff --git a/db/schema.rb b/db/schema.rb index 5f63c0f..97f2315 100644 --- a/db/schema.rb +++ b/db/schema.rb @@ -10,7 +10,7 @@ # # It's strongly recommended that you check this file into your version control system. -ActiveRecord::Schema[7.0].define(version: 2023_03_31_005733) do +ActiveRecord::Schema[7.0].define(version: 2023_07_12_103042) do # These are extensions that must be enabled in order to support this database enable_extension "pgcrypto" enable_extension "plpgsql" @@ -60,6 +60,14 @@ ActiveRecord::Schema[7.0].define(version: 2023_03_31_005733) do t.index ["member_id"], name: "index_notifications_on_member_id" end + create_table "payments", id: :uuid, default: -> { "gen_random_uuid()" }, force: :cascade do |t| + t.uuid "member_id", null: false + t.string "status" + t.datetime "created_at", null: false + t.datetime "updated_at", null: false + t.index ["member_id"], name: "index_payments_on_member_id" + end + create_table "users", id: :uuid, default: -> { "gen_random_uuid()" }, force: :cascade do |t| t.datetime "created_at", null: false t.datetime "updated_at", null: false @@ -85,4 +93,5 @@ ActiveRecord::Schema[7.0].define(version: 2023_03_31_005733) do add_foreign_key "contributions", "members" add_foreign_key "notifications", "members" + add_foreign_key "payments", "members" end diff --git a/lib/tasks/saucy.rake b/lib/tasks/saucy.rake index e11e113..ac40257 100644 --- a/lib/tasks/saucy.rake +++ b/lib/tasks/saucy.rake @@ -84,7 +84,7 @@ namespace :saucy do category = case member['membership']['membership_type_id'] when "1" then 'student' - when "2" then 'normal' + when "2" then 'employed' when "3" then 'retired' when "4" then 'unemployed' else raise "derp membership type"