From e63279e3e1daf7d0c73f8ece190a708740ebd799 Mon Sep 17 00:00:00 2001 From: stephanierousset <61418966+Stef-Rousset@users.noreply.github.com> Date: Thu, 13 Jun 2024 17:36:40 +0200 Subject: [PATCH] feat: add rake task to generate a csv file with users with pending vote (#557) * feat: add rake task to generate a csv file with users with pending vote * SMS Gateway call in rake task * i18n-tasks normalize --------- Co-authored-by: moustachu --- .env-example | 1 + Gemfile | 1 + Gemfile.lock | 2 + app/views/decidim/account/show.html.erb | 5 +- config/locales/en.yml | 2 + config/locales/fr.yml | 2 + config/secrets.yml | 1 + lib/tasks/decidim_app.rake | 68 +++++++++++++++++++++++++ 8 files changed, 79 insertions(+), 3 deletions(-) diff --git a/.env-example b/.env-example index 122facf9..23911592 100644 --- a/.env-example +++ b/.env-example @@ -88,6 +88,7 @@ RAILS_LOG_LEVEL=warn ## SMS Gateway Service (eg: decidim-half_signup) # SMS_GATEWAY_SERVICE="Decidim::SmsGatewayService" # SMS_GATEWAY_URL="https://sms.gateway.service/api" +# SMS_GATEWAY_BULK_URL="https://sms.gateway.service/api/bulk" # SMS_GATEWAY_USERNAME= # SMS_GATEWAY_PASSWORD= ## Set to replace the organization name diff --git a/Gemfile b/Gemfile index 424df619..93101e50 100644 --- a/Gemfile +++ b/Gemfile @@ -50,6 +50,7 @@ gem "faker", "~> 2.14" gem "fog-aws" gem "foundation_rails_helper", git: "https://github.com/sgruhier/foundation_rails_helper.git" gem "letter_opener_web", "~> 1.3" +gem "multipart-post" gem "nokogiri", "1.13.4" gem "omniauth-rails_csrf_protection", "~> 1.0" gem "puma", ">= 5.5.1" diff --git a/Gemfile.lock b/Gemfile.lock index ae26d2a6..e7b9688a 100644 --- a/Gemfile.lock +++ b/Gemfile.lock @@ -744,6 +744,7 @@ GEM msgpack (1.7.2) multi_json (1.15.0) multi_xml (0.6.0) + multipart-post (2.4.1) mustache (1.1.1) net-http (0.4.1) uri @@ -1168,6 +1169,7 @@ DEPENDENCIES letter_opener_web (~> 1.3) listen (~> 3.1) lograge + multipart-post nokogiri (= 1.13.4) omniauth-france_connect! omniauth-publik! diff --git a/app/views/decidim/account/show.html.erb b/app/views/decidim/account/show.html.erb index 160d55ab..94545eea 100644 --- a/app/views/decidim/account/show.html.erb +++ b/app/views/decidim/account/show.html.erb @@ -45,8 +45,7 @@ ->(locale) {locale_name(locale) }, {}, { disabled: true } - ) - %> + ) %> <% end %>

<%= t(".available_locales_helper") %>

@@ -67,4 +66,4 @@ <%= f.submit t(".update_account") %> <% end %> - \ No newline at end of file + diff --git a/config/locales/en.yml b/config/locales/en.yml index 6623ca86..9d681efe 100644 --- a/config/locales/en.yml +++ b/config/locales/en.yml @@ -38,6 +38,8 @@ en: osp_authorization_workflow: name: Authorization procedure budgets: + order_reminder: + text_message: Your vote is still pending for the participatory budget. Please reconnect to %{organization_host} to confirm it projects: count: projects_count: diff --git a/config/locales/fr.yml b/config/locales/fr.yml index c18db78a..1a4e14cb 100644 --- a/config/locales/fr.yml +++ b/config/locales/fr.yml @@ -40,6 +40,8 @@ fr: osp_authorization_workflow: name: Procédure d'autorisation budgets: + order_reminder: + text_message: Votre vote au budget participatif n'est pas terminé. Pour le terminer, reconnectez-vous sur %{organization_host} projects: count: projects_count: diff --git a/config/secrets.yml b/config/secrets.yml index 66c79445..525f2d0b 100644 --- a/config/secrets.yml +++ b/config/secrets.yml @@ -44,6 +44,7 @@ default: &default sms_gateway: service: <%= ENV.fetch("SMS_GATEWAY_SERVICE", "Decidim::Verifications::Sms::ExampleGateway") %> url: <%= ENV["SMS_GATEWAY_URL"] %> + bulk_url: <%= ENV["SMS_GATEWAY_BULK_URL"] %> username: <%= ENV["SMS_GATEWAY_USERNAME"] %> password: <%= ENV["SMS_GATEWAY_PASSWORD"] %> platform: <%= ENV["SMS_GATEWAY_PLATFORM"] %> diff --git a/lib/tasks/decidim_app.rake b/lib/tasks/decidim_app.rake index 910e012d..daba7839 100644 --- a/lib/tasks/decidim_app.rake +++ b/lib/tasks/decidim_app.rake @@ -1,5 +1,6 @@ # frozen_string_literal: true +require "net/http/post/multipart" require "decidim_app/k8s/configuration_exporter" require "decidim_app/k8s/organization_exporter" require "decidim_app/k8s/manager" @@ -76,4 +77,71 @@ namespace :decidim_app do DecidimApp::K8s::Manager.run(ENV.fetch("path", nil)) end end + + namespace :budgets do + # This task is used to send a reminder by sms to voters who haven't finished their + # vote for a budget. When you launch the task, you have to pass the id of the budget + # in a variable in terminal + desc "send a reminder to vote for budget" + task send_sms_reminder: :environment do + if (budget_id = ENV.fetch("BUDGET_ID")).nil? + p "You need to provide a budget ID" + next + end + + if (budget = Decidim::Budgets::Budget.find_by(id: budget_id)).nil? + p "Budget with id #{budget_id} not found" + next + end + + organization = budget.organization + + users_ids = Decidim::Budgets::Order.where(budget: budget) + .pending + &.pluck(:decidim_user_id) + if users_ids.empty? + p "no pending votes" + next + end + users = Decidim::User.where(id: users_ids).where.not(phone_number: nil, phone_country: nil) + + if users.blank? + p "no pending votes from users with phone number" + next + end + + filename = "send_sms_reminder_#{Time.current.year}_#{Time.current.month}_#{Time.current.day}_#{Time.current.min}.csv" + message = I18n.t("decidim.budgets.order_reminder.text_message", locale: organization.default_locale, organization_host: organization.host) + + file = Tempfile.new(filename) + CSV.open(file, "w", col_sep: ";") do |csv| + users.each do |user| + csv << ["#{user.phone_country}#{user.phone_number}", message] + end + end + file.rewind + + p "users ids: #{users.ids}" + p "csv done at #{filename}" + + api_url = Rails.application.secrets.dig(:decidim, :sms_gateway, :bulk_url) + username = Rails.application.secrets.dig(:decidim, :sms_gateway, :username) + password = Rails.application.secrets.dig(:decidim, :sms_gateway, :password) + + url = URI(api_url) + request = Net::HTTP::Post::Multipart.new(url, { + u: username, + p: password, + f: "sms", + c: "Reminder", + file: UploadIO.new(file, "text/csv", filename) + }) + + response = Net::HTTP.start(url.hostname, url.port, use_ssl: true) do |https| # pay attention to use_ssl if you need it + https.request(request) + end + + p "API response is #{response.body}" + end + end end