From 1f8b73e3d10e85c872fea4295fe51847f1cb52bd Mon Sep 17 00:00:00 2001 From: Mervin de Jong Date: Sat, 14 Sep 2024 16:35:41 +0200 Subject: [PATCH 1/3] Removed code from the old Mongoose back-end and re-organised menu's --- .../stylesheets/admin/checkout_products.css | 154 --------- .../admin/{apps.css => transactions.css} | 61 ---- .../admin/checkout_products_controller.rb | 128 -------- app/controllers/admin/home_controller.rb | 7 - app/controllers/admin/logs_controller.rb | 10 + app/controllers/admin/members_controller.rb | 22 +- app/controllers/admin/payments_controller.rb | 23 +- ...ntroller.rb => transactions_controller.rb} | 16 +- app/controllers/api/checkout_controller.rb | 144 --------- app/controllers/api/internal_controller.rb | 34 -- app/controllers/members/home_controller.rb | 12 - .../members/payments_controller.rb | 43 --- app/controllers/public/status_controller.rb | 7 +- app/javascript/application.js | 3 +- app/javascript/src/admin/apps.js | 305 ------------------ app/javascript/src/admin/index.js | 1 - app/javascript/src/admin/members.js | 151 --------- app/javascript/src/admin/transactions.js | 29 ++ app/mailers/mailings/checkout.rb | 29 -- app/models/checkout_balance.rb | 9 - app/models/checkout_card.rb | 38 --- app/models/checkout_product.rb | 96 ------ app/models/checkout_transaction.rb | 96 ------ app/models/member.rb | 9 - app/models/payment.rb | 18 -- app/views/admin/home/index.html.haml | 20 +- .../logs.html.haml => logs/index.html.haml} | 5 +- app/views/admin/payments/index.html.haml | 6 +- .../index.html.haml} | 10 +- app/views/api/checkout/info.rabl | 3 - app/views/api/checkout/products.rabl | 7 - app/views/api/checkout/recent.rabl | 7 - .../layouts/partials/_navigation.html.haml | 44 +-- .../partials/_search_payments.html.haml | 29 +- .../confirmation_instructions.html.haml | 25 -- app/views/members/home/download.html.haml | 16 - app/views/members/payments/index.html.haml | 40 --- bin/test_all_mails.rb | 2 - config/routes.rb | 75 ++--- db/seeds.rb | 1 - db/seeds/checkout.rb | 59 ---- db/seeds/payments.rb | 4 +- doc/api_readme2.md | 172 +--------- 43 files changed, 120 insertions(+), 1850 deletions(-) delete mode 100644 app/assets/stylesheets/admin/checkout_products.css rename app/assets/stylesheets/admin/{apps.css => transactions.css} (53%) delete mode 100644 app/controllers/admin/checkout_products_controller.rb create mode 100644 app/controllers/admin/logs_controller.rb rename app/controllers/admin/{apps_controller.rb => transactions_controller.rb} (60%) delete mode 100644 app/controllers/api/checkout_controller.rb delete mode 100644 app/controllers/api/internal_controller.rb delete mode 100644 app/javascript/src/admin/apps.js create mode 100644 app/javascript/src/admin/transactions.js delete mode 100644 app/mailers/mailings/checkout.rb delete mode 100644 app/models/checkout_balance.rb delete mode 100644 app/models/checkout_card.rb delete mode 100644 app/models/checkout_product.rb delete mode 100644 app/models/checkout_transaction.rb rename app/views/admin/{settings/logs.html.haml => logs/index.html.haml} (96%) rename app/views/admin/{apps/transactions.html.haml => transactions/index.html.haml} (84%) delete mode 100644 app/views/api/checkout/info.rabl delete mode 100644 app/views/api/checkout/products.rabl delete mode 100644 app/views/api/checkout/recent.rabl delete mode 100644 app/views/mailings/checkout/confirmation_instructions.html.haml delete mode 100644 db/seeds/checkout.rb diff --git a/app/assets/stylesheets/admin/checkout_products.css b/app/assets/stylesheets/admin/checkout_products.css deleted file mode 100644 index 2f5bbca9b..000000000 --- a/app/assets/stylesheets/admin/checkout_products.css +++ /dev/null @@ -1,154 +0,0 @@ -.panel-heading { - height: 39px; - padding-top: 0; - line-height: 39px; -} - -table.table.table-linked > tbody > tr:hover > td > a { - text-decoration: none; -} - -table.table.table-linked > tbody > tr > td > a:hover { - text-decoration: underline; -} - -.date-input { - display: inline-block; -} - -.date-input input { - font-weight: bold; - font-size: 14px; - line-height: 14px; - margin-left: 5px; - display: inline-block; - position: relative; - padding: 5px; - outline: none; - background: transparent; -} - -.update-side-bar { - position: fixed; - right: 0; - max-height: calc(100% - 70px); - top: 65px; - width: calc(50% - 100px); - overflow-y: scroll; -} - -.new-product { - width: 36.5px; - height: 36.5px; - font-size: 30px; - padding: 0; - line-height: 30px; - float: right; -} - -.card-header-text { - float: left; - line-height: 36.5px; -} - -.edit-product-form, .edit-product-form-lower { - margin-left: 158px; -} - -.save-btn { - margin-top: 20px; - float: right; -} - -@media (min-width: 768px) { - form .panel-body { - position: relative; - } - - form span.thumb { - position: absolute; - top: 67px; - height: 128px; - width: 128px; - overflow: hidden; - } - - table.table.table-linked > tbody > tr > td.text-right { - padding-right: 30px; - } -} - -@media (max-width: 1400px) { - .product-cards { - flex-flow: wrap-reverse; - } - - .col-md-8, .col-md-4 { - max-width: 100%; - flex: none; - } - - .edit-product-form-lower { - margin-left: 0px; - } -} - -@media (max-width: 1030px) { - .update-side-bar { - position: relative; - float: left; - width: 100%; - padding: 0; - top: inherit; - } - - .col-md-6 { - max-width: 100%; - flex: none; - } -} - -tr.total { - font-weight: bold; -} - -.table span.fa-sort-asc { - color: green; - position: relative; - top: 6px; -} - -.table span.fa-sort-desc { - color: red; -} - -tr.inactive { - text-decoration: line-through; -} - -p.uuid { - margin-bottom: 0; -} - -.ui-select.year { - width: 110px; - margin-left: 5px; -} - -.ui-select.year select { - font-size: 14px; - line-height: 14px; -} - -a.col-md-4, a.col-md-4:hover { - text-decoration: none; -} - -a.panel:hover { - text-decoration: none; -} - -.new-product a { - color: #fff; - text-decoration: none; -} \ No newline at end of file diff --git a/app/assets/stylesheets/admin/apps.css b/app/assets/stylesheets/admin/transactions.css similarity index 53% rename from app/assets/stylesheets/admin/apps.css rename to app/assets/stylesheets/admin/transactions.css index 3c5d918e3..b1871e610 100644 --- a/app/assets/stylesheets/admin/apps.css +++ b/app/assets/stylesheets/admin/transactions.css @@ -39,67 +39,6 @@ tr.total { border-top: 2px solid #dddddd; } -/* Members - [Member] - Checkout */ -div#credit.input-group { - display: inline; - width: auto; - float: right; -} - -div#credit.input-group > span.input-group-btn, -div#credit.input-group > span { - float: right; - margin-left: 2px; -} - -div#credit.input-group > *, -div#credit.input-group > * > * { - display: inline-block; -} - -div#credit.input-group > .input-symbol > input { - width: 80px; -} - -div#credit.input-group select { - background-color: white; - height: 32px; -} - -/* Apps - Checkout - Opwaarderen */ -#credit form.form-inline > .form-group { - padding: 0; -} - -@media (min-width: 768px) { - #credit form.form-inline > .form-group { - display: block; - } -} - -@media (min-width: 992px) { - #credit form.form-inline > .form-group.amount { - margin-left: 3.33%; - width: 30%; - } -} - -#credit form.form-inline > .form-group > select.form-control, -#credit form.form-inline > .form-group > input.form-control, -#credit form.form-inline > .form-group > button.form-control { - width: 100%; - height: 30px; - margin: 5px 0; - padding: 1px 12px; -} - -#credit .panel-body > ul.dropdown-menu { - display: none; - position: absolute; - left: 0; - top: 50px; -} - .table span.fa-sort-asc { color: green; position: relative; diff --git a/app/controllers/admin/checkout_products_controller.rb b/app/controllers/admin/checkout_products_controller.rb deleted file mode 100644 index 8b060e35d..000000000 --- a/app/controllers/admin/checkout_products_controller.rb +++ /dev/null @@ -1,128 +0,0 @@ -#:nodoc: -class Admin::CheckoutProductsController < ApplicationController - # replaced with calls in each of the methods - # impressionist :actions => [ :activate_card, :change_funds ] - respond_to :json, only: [:activate_card, :change_funds] - - def index - @products = CheckoutProduct.order(active: :desc, category: :asc, name: :asc).last_version - @years = (2015..Date.today.study_year).map { |year| ["#{ year }-#{ year + 1 }", year] }.reverse - - @new = CheckoutProduct.new - - render('admin/apps/products') - end - - def show - @products = CheckoutProduct.order(active: :desc, category: :asc, name: :asc).last_version - @years = (2015..Date.today.study_year).map { |year| ["#{ year }-#{ year + 1 }", year] }.reverse - - @product = CheckoutProduct.find_by(id: params[:id]) - @total = @product.sales(params['year']).map do |sale| - sale.first[0].price * sale.first[1] unless sale.first[1].nil? - end.compact.inject(:+) - - render('admin/apps/products') - end - - def create - @new = CheckoutProduct.new(product_post_params) - - if @new.save - redirect_to(checkout_product_path(@new)) - else - @products = CheckoutProduct.order(:category, :name).last_version - @years = (2015..Date.today.study_year).map do |year| - ["#{ year }-#{ year + 1 }", year] - end.reverse - - render('admin/apps/products') - end - end - - def update - @product = CheckoutProduct.find_by(id: params[:id]) - - if @product.update(product_post_params) - # if a new product is created redirect to it - product = CheckoutProduct.find_by(parent: @product.id) - prod_id = product ? product.id.to_s : @product.id.to_s - - redirect_to(checkout_product_path(product || @product.id, anchor: "product_#{ prod_id }")) - else - @years = (2015..Date.today.study_year).map do |year| - ["#{ year }-#{ year + 1 }", year] - end.reverse - @products = CheckoutProduct.order(:category, :name).last_version - - render('admin/apps/products') - end - end - - def flip_active - @product = CheckoutProduct.find(params[:checkout_product_id]) - - head(:internal_server_error) unless @product.update(product_flipactive_params) - end - - def change_funds - if params[:uuid] - card = CheckoutCard.joins(:checkout_balance).find_by(uuid: params[:uuid]) - transaction = CheckoutTransaction.new(price: params[:amount], checkout_card: card) - - elsif params[:member_id] - transaction = CheckoutTransaction.new( - price: params[:amount], - checkout_balance: CheckoutBalance.find_by!(member_id: params[:member_id]), - payment_method: params[:payment_method] - ) - - else - render(status: :bad_request, json: I18n.t('checkout.error.identifier')) - return - end - - if transaction.save - impressionist(transaction) - render(status: :created, json: transaction) - else - render(status: :bad_request, json: { - errors: transaction.errors - }) - end - end - - def activate_card - card = CheckoutCard.find_by!(uuid: params[:uuid]) - - if params[:_destroy] - card.destroy - - render(status: :no_content, json: '') - return - end - - card.update(active: true) - - if card.save - impressionist(card) - render(status: :ok, json: card.to_json) - else - render(status: :bad_request, json: card.errors.full_messages) - end - end - - private - - def product_post_params - params.require(:checkout_product).permit(:name, - :price, - :category, - :active, - :image) - end - - def product_flipactive_params - params.require(:checkout_product).permit(:active) - end -end diff --git a/app/controllers/admin/home_controller.rb b/app/controllers/admin/home_controller.rb index 376864322..e483f8836 100644 --- a/app/controllers/admin/home_controller.rb +++ b/app/controllers/admin/home_controller.rb @@ -7,13 +7,6 @@ def index @activities = Activity.where("start_date >= ?", Date.to_date(Time.zone.today.study_year)).count - @transactions = CheckoutTransaction.count(:all) - - @recent = CheckoutTransaction.where( - "created_at >= ?", - Time.zone.now.beginning_of_day - ).order(created_at: :desc).take(12) - @recentactivities = Payment.where( "created_at >= ?", Time.zone.now.beginning_of_day diff --git a/app/controllers/admin/logs_controller.rb b/app/controllers/admin/logs_controller.rb new file mode 100644 index 000000000..b3bfbbef4 --- /dev/null +++ b/app/controllers/admin/logs_controller.rb @@ -0,0 +1,10 @@ +#:nodoc: +class Admin::LogsController < ApplicationController + def index + @limit = params[:limit] ? params[:limit].to_i : 50 + + @pagination, @impressions = pagy(Impression.all.order(created_at: :desc), + items: params[:limit] ||= 50) + @total_log_items = Impression.count + end +end diff --git a/app/controllers/admin/members_controller.rb b/app/controllers/admin/members_controller.rb index 82f3f7b06..503c8b0c1 100644 --- a/app/controllers/admin/members_controller.rb +++ b/app/controllers/admin/members_controller.rb @@ -43,14 +43,6 @@ def show @years = (@member.join_date.study_year..Date.today.study_year).map do |year| ["#{ year }-#{ year + 1 }", year] end.reverse - - # Pagination for checkout transactions - @limit = params[:limit] ? params[:limit].to_i : 10 - - @pagination, @transactions = pagy(CheckoutTransaction - .where(checkout_balance: CheckoutBalance - .find_by(member_id: params[:id])) - .order(created_at: :desc), items: 10) end def new @@ -147,18 +139,13 @@ def send_email end def destroy - @member = Member.includes(:checkout_balance).find(params[:id]) + @member = Member.find(params[:id]) impressionist(@member) flash[:notice] = [] if @member.destroy flash[:notice] << I18n.t('activerecord.errors.models.member.destroy.info', name: @member.name) - unless @member.checkout_balance.nil? - flash[:notice] << I18n.t('activerecord.errors.models.member.destroy.checkout_emptied', - balance: view_context.number_to_currency(@member.checkout_balance.balance, - unit: '€')) - end unless @member.mailchimp_interests.nil? flash[:notice] << I18n.t('activerecord.errors.models.member.destroy.mailchimp_queued') end @@ -177,13 +164,6 @@ def payment_whatsapp render(layout: false, content_type: "text/plain") end - def set_card_disabled - @uuid = params[:uuid] - @to = params[:to] - @card = CheckoutCard.find_by(uuid: @uuid) - @card.update(disabled: @to) - end - private def member_post_params diff --git a/app/controllers/admin/payments_controller.rb b/app/controllers/admin/payments_controller.rb index 576f4d861..2915af64c 100644 --- a/app/controllers/admin/payments_controller.rb +++ b/app/controllers/admin/payments_controller.rb @@ -16,15 +16,6 @@ def index [activity, days, sent_mails] end - # Get checkout transactions that were purchased by pin of yesterday - @checkout_transactions = CheckoutTransaction.where( - 'DATE(checkout_transactions.created_at) = DATE(?) AND payment_method = \'Gepind\'', 1.day.ago - ).order(created_at: :desc) - @dat = @checkout_transactions.map do |x| - { member_id: x.checkout_balance.member.id, name: x.checkout_balance.member.name, price: x.price, - date: x.created_at.to_date } - end.to_json - # Counts if the activity has debtors and if 4 weeks have passed (last friday # is more than 21 days ago since 0 counts aswell) @late_activities = Activity.debtors.select do |activity| @@ -61,18 +52,6 @@ def whatsapp_redirect redirect_to(url.to_s) end - def update_transactions - checkout_transactions = CheckoutTransaction.where( - 'DATE(checkout_transactions.created_at) = DATE(?) AND payment_method = \'Gepind\'', params[:start_date] - ).order(created_at: :desc) - data = checkout_transactions.map do |x| - { member_id: x.checkout_balance.member.id, name: x.checkout_balance.member.name, price: x.price, - date: x.created_at.to_date } - end - - render(json: data) - end - def export_payments unless params[:export_type].present? && params[:start_date].present? && params[:end_date].present? return head(:bad_request) @@ -98,7 +77,7 @@ def export_payments '%Y-%m-%d') }.csv") end format.js do - render(js: "window.open(\"#{ transactions_export_path( + render(js: "window.open(\"#{ payment_transactions_export_path( format: :csv, start_date: params[:start_date], end_date: params[:end_date], diff --git a/app/controllers/admin/apps_controller.rb b/app/controllers/admin/transactions_controller.rb similarity index 60% rename from app/controllers/admin/apps_controller.rb rename to app/controllers/admin/transactions_controller.rb index f7c3fb419..dcb1d215d 100644 --- a/app/controllers/admin/apps_controller.rb +++ b/app/controllers/admin/transactions_controller.rb @@ -1,18 +1,6 @@ #:nodoc: -class Admin::AppsController < ApplicationController - def checkout - @pagination = 5 - - @pagination, @transactions = pagy(CheckoutTransaction.includes(:checkout_card) - .order(created_at: :desc), items: params[:limit] ||= 20) - - @cards = CheckoutCard.joins(:member).select(:id, :uuid, :member_id).where(active: false) - - @credit = CheckoutBalance.sum(:balance) - @products = CheckoutProduct.where(active: true).count - end - - def transactions +class Admin::TransactionsController < ApplicationController + def index @transactions = Payment.order(created_at: :desc) @transactions = @transactions.search_by_name(params[:search]) if params[:search].present? diff --git a/app/controllers/api/checkout_controller.rb b/app/controllers/api/checkout_controller.rb deleted file mode 100644 index 29fa77037..000000000 --- a/app/controllers/api/checkout_controller.rb +++ /dev/null @@ -1,144 +0,0 @@ -# Controller used for checkout before oauth was implemented -# @deprecated controller, base controller should be replaced with oauth -class Api::CheckoutController < ActionController::Base - protect_from_forgery except: %i[info purchase create products recent] - before_action :authenticate_checkout, only: %i[info purchase create products recent] - before_action :authenticate_card, only: %i[info purchase] - - respond_to :json - - def products - @products = CheckoutProduct.where(active: true) - end - - def recent - recent = CheckoutTransaction.joins(:checkout_card).where( - checkout_card: CheckoutCard.where(member_id: CheckoutCard.find_by(uuid: params[:uuid]).member_id) - ).order(created_at: :desc).limit(5) - items = [] - recent.each do |item| - item.items.each do |id| - items << id - end - end - products = CheckoutProduct.where(id: items).limit(5).to_a - @products = items.map { |id| products.find { |product| product.id == id } } - end - - def info - @card = CheckoutCard.joins(:member, :checkout_balance).select(:id, :uuid, :first_name, - :balance, :active).find_by(uuid: params[:uuid]) - - return head(:not_found) unless @card - end - - def purchase - card = CheckoutCard.find_by!(uuid: params[:uuid]) - - transaction = CheckoutTransaction.new(items: ahelper(params[:items]), checkout_card: card) - - if transaction.save! - render(status: :created, json: { - uuid: card.uuid, - first_name: card.member.first_name, - balance: card.checkout_balance.balance + transaction.price, - created_at: transaction.created_at - }) - else - i18n_scope = %i[activerecord errors models checkout_transaction attributes] - - not_liquor_time_translation = I18n.t('items.not_liquor_time', scope: i18n_scope) - insufficient_credit_translation = I18n.t('price.insufficient_credit', scope: i18n_scope) - - case transaction.errors - when transaction.errors[:items].includes(not_liquor_time_translation) - render(status: :not_acceptable, json: { - message: not_liquor_time_translation - }) - when transaction.errors[:price].includes(insufficient_credit_translation) - render(status: :payload_too_large, json: { - message: I18n.t(insufficient_credit_translation, scope: i18n_scope), - balance: card.checkout_balance.balance, - items: ahelper(params[:items]), - costs: transaction.price - }) - else - render(status: :bad_request, json: { - errors: transaction.errors - }) - end - end - end - - def create - head(:conflict) && return unless CheckoutCard.find_by(uuid: params[:uuid]).nil? - - card = CheckoutCard.new(uuid: params[:uuid], - member: Member.find_by!(student_id: params[:student]), description: params[:description]) - - if card.save - card.send_confirmation! - render(status: :created, - json: CheckoutCard.joins(:member, :checkout_balance).select( - :id, - :uuid, - :first_name, - :balance - ).find_by!(uuid: params[:uuid]).to_json) - else - head(:conflict) - end - end - - def confirm - card = CheckoutCard.where(confirmation_token: params['confirmation_token']).first - redirect_to(:new_user_session) - - if card.nil? - flash[:alert] = I18n.t('checkout.card.nil') - return - end - - if card.active - flash[:alert] = I18n.t('checkout.card.already_activated') - return - end - - if card.update(active: true) - flash[:notice] = I18n.t('checkout.card.activated') - else - flash[:alert] = I18n.t('checkout.card.not_activated') - end - end - - private - - def ahelper(obj) - return [] if obj.empty? - - begin - return Array.new(1, obj.to_i) if obj.is_number? - - return JSON.parse(obj) - rescue StandardError - return [] - end - end - - # TODO: implement for OAuth client credentials - def authenticate_checkout - if params[:token] != ENV['CHECKOUT_TOKEN'] - head(:forbidden) - nil - end - end - - def authenticate_card - @uuid = params[:uuid] - @card = CheckoutCard.find_by(uuid: @uuid) - render(status: :not_found && return) if @card.nil? - render(status: :unauthorized, json: I18n.t('checkout.error.not_activated')) unless @card.active - render(status: :unauthorized, json: I18n.t('checkout.error.disabled')) if @card.disabled - (@card.active and !@card.disabled) - end -end diff --git a/app/controllers/api/internal_controller.rb b/app/controllers/api/internal_controller.rb deleted file mode 100644 index 06186ed53..000000000 --- a/app/controllers/api/internal_controller.rb +++ /dev/null @@ -1,34 +0,0 @@ -# Internal API controller -class Api::InternalController < ActionController::Base - protect_from_forgery - before_action :authenticate_internal - respond_to :json - - def member_by_studentid - @mongoose_user = Member.select(:id, :first_name, :infix, :last_name, :birth_date, - :email).find_by(student_id: params[:student_number]) - return head(:no_content) unless @mongoose_user - end - - def member_by_id - @mongoose_user = Member.select(:id, :first_name, :infix, :last_name, - :birth_date).find(params[:id]) - return head(:no_content) unless @mongoose_user - end - - def authenticate_internal - return unless request.headers['Authorization'] != ENV['CHECKOUT_TOKEN'] - - head(:forbidden) - nil - end - - def authenticate_card - @uuid = params[:uuid] - @card = CheckoutCard.find_by(uuid: @uuid) - render(status: :not_found && return) if @card.nil? - render(status: :unauthorized, json: I18n.t('checkout.error.not_activated')) unless @card.active - render(status: :unauthorized, json: I18n.t('checkout.error.disabled')) if @card.disabled - (@card.active and !@card.disabled) - end -end diff --git a/app/controllers/members/home_controller.rb b/app/controllers/members/home_controller.rb index 009365125..a68b9c57a 100644 --- a/app/controllers/members/home_controller.rb +++ b/app/controllers/members/home_controller.rb @@ -8,8 +8,6 @@ class Members::HomeController < ApplicationController def index @member = Member.find(current_user.credentials_id) - # information of the middlebar - @balance = CheckoutBalance.find_by(member_id: current_user.credentials_id) @debt = Participant .where(paid: false, member: @member, reservist: false) .joins(:activity) @@ -34,13 +32,6 @@ def index .joins(:participants) .where(participants: { member: @member, reservist: false }) .order('start_date DESC') - - @transactions = CheckoutTransaction.where( - checkout_balance: CheckoutBalance.find_by( - member_id: current_user.credentials_id - ) - ).order(created_at: :desc).limit(10) # ParticipantTransaction.all # - @transaction_costs = Settings.mongoose_ideal_costs end def edit @@ -85,9 +76,6 @@ def update def download @member = Member.includes(:activities, :groups, :educations).find(current_user.credentials_id) - @transactions = CheckoutTransaction.where( - checkout_balance: CheckoutBalance.find_by(member_id: current_user.credentials_id) - ).order(created_at: :desc) send_data(render_to_string(layout: false), filename: "#{ @member.name.downcase.tr(' ', '-') }.html", diff --git a/app/controllers/members/payments_controller.rb b/app/controllers/members/payments_controller.rb index 04238f40a..746e1c743 100644 --- a/app/controllers/members/payments_controller.rb +++ b/app/controllers/members/payments_controller.rb @@ -7,12 +7,6 @@ class Members::PaymentsController < ApplicationController def index @member = Member.find(current_user.credentials_id) @participants = @member.unpaid_activities - @transactions = CheckoutTransaction.where( - checkout_balance: CheckoutBalance.find_by( - member_id: current_user.credentials_id - ) - ).order(created_at: :desc).limit(10) # ParticipantTransaction.all # - @transaction_costs = Settings.mongoose_ideal_costs end def pay_activities @@ -75,43 +69,6 @@ def self.join_with_char_limit(collection, separator, maxlength) return ".. & #{ collection.length } meer" end - def add_funds - member = Member.find(current_user.credentials_id) - balance = CheckoutBalance.find_or_create_by!(member: member) - description = I18n.t('activerecord.errors.models.payment.attributes.checkout') - amount = transaction_params[:amount].gsub(",", ".").to_f - - if amount < 1 - flash[:warning] = I18n.t('failed', scope: 'activerecord.errors.models.payment') - redirect_to(member_payments_path) - return - end - - if balance.nil? - flash[:warning] = I18n.t('failed', scope: 'activerecord.errors.models.payment') - redirect_to(member_payments_path) - return - end - - payment = Payment.new( - description: description, - amount: amount, - member: member, - issuer: transaction_params[:bank], - payment_type: :ideal, - - transaction_id: nil, - transaction_type: :checkout, - redirect_uri: member_payments_path - ) - if payment.save - redirect_to(payment.payment_uri) - else - flash[:warning] = I18n.t('failed', scope: 'activerecord.errors.models.payment') - redirect_to(members_home_path) - end - end - private def transaction_params diff --git a/app/controllers/public/status_controller.rb b/app/controllers/public/status_controller.rb index d0d76e565..6594e2baf 100644 --- a/app/controllers/public/status_controller.rb +++ b/app/controllers/public/status_controller.rb @@ -48,7 +48,7 @@ def update def destroy @token = Token.find_by!(token: params[:token], intent: :consent) - @member = Member.includes(:checkout_balance).find(@token.object.id) + @member = Member.find(@token.object.id) impressionist(@member) flash[:notice] = [] @@ -59,11 +59,6 @@ def destroy if @member.destroy @token.destroy flash[:notice] << I18n.t('activerecord.errors.models.member.destroy.info', name: @member.name) - unless @member.checkout_balance.nil? - flash[:notice] << I18n.t('activerecord.errors.models.member.destroy.checkout_emptied', - balance: view_context.number_to_currency(@member.checkout_balance.balance, - unit: '€')) - end flash[:notice] << I18n.t('activerecord.errors.models.member.destroy.mailchimp_queued') redirect_to(users_root_url) diff --git a/app/javascript/application.js b/app/javascript/application.js index 33655b821..94a13e051 100644 --- a/app/javascript/application.js +++ b/app/javascript/application.js @@ -24,7 +24,6 @@ import "../../vendor/assets/javascripts/bootstrap-file-input"; import "./src/lib/dropdown"; import "./src/lib/editor"; import "./src/lib/mail"; -import "./src/admin/index.js"; import "./src/language.js"; -import "./src/application.js"; +import "./src/admin/index.js"; import "./src/admin/datepicker"; diff --git a/app/javascript/src/admin/apps.js b/app/javascript/src/admin/apps.js deleted file mode 100644 index 1b1acf6f9..000000000 --- a/app/javascript/src/admin/apps.js +++ /dev/null @@ -1,305 +0,0 @@ -// -//= require bootstrap-file-input -import $ from "jquery"; -import I18n from "../translations.js"; -import toastr from "toastr"; - -$(document).on("ready page:load turbolinks:load", function () { - bind_flip(); - $(document).on("click", ".allow-focus", function (e) { - e.stopPropagation(); - }); - - $('form .input-group-btn .file-input-wrapper input[type="file"]').on( - "change", - function () { - if (this.files && this.files[0]) { - $("form .input-group input#output").val(this.files[0].name); - } - }, - ); - - // activate card - $("div#cards ul.list-group .btn-group button:nth-child(1)").bind( - "click", - function () { - var button = $(this); - var row = $(this).closest(".list-group-item"); - var token = encodeURIComponent( - $(this).closest(".page").attr("data-authenticity-token"), - ); - - $(button).attr("disabled", "disabled"); - - $.ajax({ - url: "/apps/cards", - type: "PATCH", - data: { - uuid: $(row).attr("data-uuid"), - authenticity_token: token, - }, - }) - .done(function () { - toastr.success(I18n.t("checkout.card.activated")); - $(row).remove(); - }) - .fail(function () { - toastr.error(I18n.t("checkout.card.not_activated")); - $(button).removeAttr("disabled"); - }); - }, - ); - - $("div#cards ul.list-group .btn-group button:nth-child(2)").bind( - "click", - function () { - var button = $(this); - var row = $(this).closest(".list-group-item"); - var token = encodeURIComponent( - $(this).closest(".page").attr("data-authenticity-token"), - ); - - $(button).attr("disabled", "disabled"); - - $.ajax({ - url: "/apps/cards", - type: "PATCH", - data: { - uuid: $(row).attr("data-uuid"), - authenticity_token: token, - _destroy: true, - }, - }) - .done(function () { - toastr.warning(I18n.t("checkout.card.removed")); - $(row).remove(); - }) - .fail(function () { - toastr.error(I18n.t("checkout.card.not_removed")); - $(button).removeAttr("disabled"); - }); - }, - ); - - var credit = $("#credit"); - // search members using dropdown - var cardHolder = credit.find("input#card_holder"); - var amountInput = credit.find(".form-group input#amount"); - var paymentMethodInput = credit.find("select#payment_method"); - cardHolder.search().on("selected", function (event, id, name) { - $(this).attr("disabled", "disabled").val(name); - credit - .find(".form-group#search_card") - .attr("data-id", id) - .removeClass("col-md-12") - .addClass("col-md-4"); - - credit.find(".form-group").css("display", "block"); - amountInput.focus(); - }); - - // catch [ESC] to cancel - amountInput.on("keyup", function (event, code) { - if (event.keyCode === 27 || code === 27) { - credit - .find(".form-group#search_card input") - .removeAttr("disabled") - .val(""); - credit.find(".form-group:not(#search_card)").css("display", "none"); - credit - .find(".form-group#search_card") - .removeAttr("data-id") - .removeClass("col-md-4") - .addClass("col-md-12"); - cardHolder.focus(); - $(this).val(""); - } - }); - - // after member is selected, set an amount - credit.find("form.form-inline").on("submit", function (event) { - var token = encodeURIComponent( - $(this).closest(".page").attr("data-authenticity-token"), - ); - - event.preventDefault(); - if (amountInput.prop("disabled")) return; - - if (!amountInput.val()) { - toastr.error(I18n.t("admin.members.top_up_error")); - return; - } - - var price = amountInput.val(); - - // Make it a bit more pretty - if (!isNaN(price)) $(this).val(parseFloat(price).toFixed(2)); - - amountInput.prop("disabled", true); - - $.ajax({ - url: "/apps/transactions", - type: "PATCH", - data: { - member_id: credit.find(".form-group#search_card").attr("data-id"), - amount: price, - payment_method: paymentMethodInput.val(), - authenticity_token: token, - }, - }) - .done(function (data) { - amountInput.prop("disabled", false); - toastr.success(I18n.t("admin.members.top_up")); - - //toevoegen aan de lijst - $("#transactions").trigger("transaction_added", data); //TODO - - //formulier terugveranderen - amountInput.trigger("keyup", [27]); - - //Reset select (payment_method) - paymentMethodInput.val(""); - }) - .fail(function (data) { - amountInput.prop("disabled", false); - - if (data.status === 404) - toastr.error(I18n.t("checkout.card.not_found")); - - if (data.status === 413) toastr.error(data.responseText, data.status); - - if (data.status === 400) toastr.error(I18n.t("checkout.error.numeric")); - }); - }); - - // [DELETE] checkout_product - $("#products button.destroy").on("click", function () { - var id = $(this).closest("tr").attr("data-id"); - var token = encodeURIComponent( - $(this).closest(".page").attr("data-authenticity-token"), - ); - var row = $(this).closest("tr"); - - if ( - !confirm( - I18n.t("admin.general.remove", { user: $(row).find("a").html() }), - ) - ) - return; - - $.ajax({ - url: "/apps/products", - type: "DELETE", - data: { - id: id, - authenticity_token: token, - }, - }) - .done(function () { - toastr.warning( - `${$(row).find("a").html()} ${I18n.t("admin.general.removed")}`, - ); - $(row).remove(); - }) - .fail(function (error) { - toastr.error(error.statusText, error.status); - }); - }); - - $(".date-input input").on("change", function () { - var params = {}; - - params.date = $(this).val(); - location.search = $.param(params); - }); - - $("form").on("submit", function () { - $(this).find('button[type="submit"].wait').addClass("disabled"); - }); -}); - -function bind_flip() { - //Reset all event handlers - $("#products button").off("click"); - - $("#products").find("button.activate").on("click", product.activate); - - $("#products").find("button.deactivate").on("click", product.deactivate); -} - -var product = { - deactivate: function () { - var row = $(this).closest("tr"); - - $.ajax({ - url: "/apps/products/" + row.attr("data-id") + "/flip", - type: "PATCH", - data: { - checkout_product: { - active: false, - }, - }, - }) - .done(function () { - toastr.success( - `${$(row).find("a").html()} ${I18n.t( - "checkout.products.deactivated", - )}`, - ); - - $(row) - .addClass("inactive") - .find("button.deactivate") - .empty() - .removeClass("deactivate btn-warning") - .addClass("activate btn-primary") - .append( - ` ${I18n.t( - "checkout.products.deactivate", - )}`, - ); - - //Reset all event handlers - bind_flip(); - }) - .fail(function (error) { - toastr.error(error.statusText, error.status); - }); - }, - - activate: function () { - var row = $(this).closest("tr"); - - $.ajax({ - url: "/apps/products/" + row.attr("data-id") + "/flip", - type: "PATCH", - data: { - checkout_product: { - active: true, - }, - }, - }) - .done(function () { - toastr.success( - `${$(row).find("a").html()} ${I18n.t("checkout.products.activated")}`, - ); - - $(row) - .removeClass("inactive") - .find("button.activate") - .empty() - .removeClass("activate btn-primary inactive") - .addClass("deactivate btn-warning") - .append( - ` ${I18n.t( - "checkout.products.activate", - )}`, - ); - - bind_flip(); - }) - .fail(function (error) { - toastr.error(error.statusText, error.status); - }); - }, -}; diff --git a/app/javascript/src/admin/index.js b/app/javascript/src/admin/index.js index 15bbaea2c..be7ebf7f4 100644 --- a/app/javascript/src/admin/index.js +++ b/app/javascript/src/admin/index.js @@ -1,5 +1,4 @@ import "./activities.js"; -import "./apps.js"; import "./editor.js"; import "./groups.js"; import "./main.js"; diff --git a/app/javascript/src/admin/members.js b/app/javascript/src/admin/members.js index 88ce86d75..e2062250d 100644 --- a/app/javascript/src/admin/members.js +++ b/app/javascript/src/admin/members.js @@ -132,155 +132,4 @@ $(document).on("ready page:load turbolinks:load", function () { } }); } - - // after member is selected, set an amount - var creditInputGroup = $("#credit.input-group"); - var inputAmount = creditInputGroup.find("input#amount"); - var paymentMethodInput = creditInputGroup.find("select#payment_method"); - creditInputGroup.find("#upgrade-btn").on("click", function () { - var token = encodeURIComponent( - $(this).closest(".page").attr("data-authenticity-token"), - ); - - if (!inputAmount.val()) { - toastr.error(I18n.t("admin.members.top_up_error")); - return; - } - - if (inputAmount.prop("disabled")) return; - - var price = $(inputAmount).val(); - - // Make it a bit more pretty - if (!isNaN(price)) $(this).val(parseFloat(price).toFixed(2)); - - inputAmount.prop("disabled", true); - - $.ajax({ - url: "/apps/transactions", - type: "PATCH", - data: { - member_id: creditInputGroup.attr("data-member-id"), - amount: price, - payment_method: paymentMethodInput.val(), - authenticity_token: token, - }, - }) - .done(function (data) { - inputAmount.prop("disabled", false); - toastr.success(I18n.t("admin.members.top_up")); - - //toevoegen aan de lijst - $("#transactions").trigger("transaction_added", data); //TODO - - //remove from input and select - paymentMethodInput.val(""); - inputAmount.val(""); - }) - .fail(function (data) { - inputAmount.prop("disabled", false); - - if (!data.responseJSON) { - toastr.error(data.statusText, data.status); - return; - } - - let errors = data.responseJSON.errors; - let text = ""; - for (let attribute in errors) { - for (let error of errors[attribute]) text += error + ", "; - - // remove last colon and space - text = text.slice(0, -2); - text += "
"; - } - // remove last line break - text = text.slice(0, -5); - - toastr.error(text); - }); - }); - - destroy(null); - - $("#memberscards button").on("click", button_action); - - function button_action() { - let row = $(this).closest("tr"); - let status = $(row).children(".cardstatus"); - let uuid = row.attr("data-uuid"); - let memberid = row.attr("data-member-id"); - let token = encodeURIComponent( - $(this).closest(".page").attr("data-authenticity-token"), - ); - - let tobeactivated = row.attr("data-active") == 0; - let disabled = row.attr("data-disabled") == 1; - - let entry = - "admin.cards." + - (tobeactivated ? "" : disabled ? "re" : "de") + - "activate_confirm"; - if (!confirm(I18n.t(entry, { uuid: uuid }))) return; - - let url = tobeactivated - ? "/apps/cards" - : "/members/" + memberid + "/set_card_disabled/" + uuid; - let successmsg = tobeactivated - ? I18n.t("checkout.card.activated") - : disabled - ? I18n.t("admin.cards.activate_success", { uuid: uuid }) - : I18n.t("admin.cards.deactivate_success", { uuid: uuid }); - - $.ajax({ - url: url, - type: "PATCH", - data: { - authenticity_token: token, - uuid: uuid, // only needed for 'to be activated', - to: !disabled, // only needed for toggling 'disabled' - }, - }) - .done(() => { - // Remove current classes - if (tobeactivated) { - status.removeClass("text-info"); - $(this).removeClass("activate btn-primary"); - row.attr("data-active", 1); - } else if (disabled) { - status.removeClass("text-muted"); - $(this).removeClass("reactivate btn-warning"); - } else { - $(this).removeClass("deacticate btn-danger"); - } - // Add new classes & content - if (disabled ^ tobeactivated) { - status.empty().append(I18n.t("admin.cards.active")); - $(this) - .empty() - .append( - '' + I18n.t("admin.cards.deactivate"), - ) - .addClass("deactivate btn-danger"); - row.attr("data-disabled", 0); - } else { - status - .empty() - .append(I18n.t("admin.cards.deactivated")) - .addClass("text-muted"); - $(this) - .empty() - .append( - '' + - I18n.t("admin.cards.reactivate"), - ) - .addClass("reactivate btn-warning"); - row.attr("data-disabled", 1); - } - toastr.success(successmsg); - }) - .fail((e) => { - toastr.error(e.statusText, e.status); - }); - } }); diff --git a/app/javascript/src/admin/transactions.js b/app/javascript/src/admin/transactions.js new file mode 100644 index 000000000..435affd54 --- /dev/null +++ b/app/javascript/src/admin/transactions.js @@ -0,0 +1,29 @@ +// +//= require bootstrap-file-input +import $ from "jquery"; + +$(document).on("ready page:load turbolinks:load", function () { + $(document).on("click", ".allow-focus", function (e) { + e.stopPropagation(); + }); + + $('form .input-group-btn .file-input-wrapper input[type="file"]').on( + "change", + function () { + if (this.files && this.files[0]) { + $("form .input-group input#output").val(this.files[0].name); + } + }, + ); + + $(".date-input input").on("change", function () { + var params = {}; + + params.date = $(this).val(); + location.search = $.param(params); + }); + + $("form").on("submit", function () { + $(this).find('button[type="submit"].wait').addClass("disabled"); + }); +}); diff --git a/app/mailers/mailings/checkout.rb b/app/mailers/mailings/checkout.rb deleted file mode 100644 index e4f6f46cf..000000000 --- a/app/mailers/mailings/checkout.rb +++ /dev/null @@ -1,29 +0,0 @@ -#:nodoc: -module Mailings - #:nodoc: - class Checkout < ApplicationMailer - def confirmation_instructions(card, confirmation_url) - Rails.logger.debug(confirmation_url) if Rails.env.development? - - subject_name = "#{ I18n.t('association_name') } | #{ I18n.t('mailings.checkout.subject') }" - - html = render_to_string(layout: 'mailer', locals: { - name: card.member.first_name, - confirmation_url: confirmation_url, - subject: subject_name - }) - - text = <<~PLAINTEXT - #{ I18n.t('mailings.greeting') } #{ card.member.first_name }, - - #{ I18n.t('mailings.checkout.confirm_card_link', confirm_url: confirmation_url) } - - #{ I18n.t('mailings.best_regards') } - - #{ I18n.t('mailings.signature') } - PLAINTEXT - - return mail(card.member.email, nil, subject_name, html, text) - end - end -end diff --git a/app/models/checkout_balance.rb b/app/models/checkout_balance.rb deleted file mode 100644 index adb22893f..000000000 --- a/app/models/checkout_balance.rb +++ /dev/null @@ -1,9 +0,0 @@ -#:nodoc: -class CheckoutBalance < ApplicationRecord - validates :balance, presence: true - validates :member, presence: true - - belongs_to :member - has_many :checkout_cards, - dependent: :destroy -end diff --git a/app/models/checkout_card.rb b/app/models/checkout_card.rb deleted file mode 100644 index 27e938d2b..000000000 --- a/app/models/checkout_card.rb +++ /dev/null @@ -1,38 +0,0 @@ -#:nodoc: -class CheckoutCard < ApplicationRecord - validates :uuid, presence: true - validates :member, presence: true - validates :checkout_balance, presence: true - - has_many :checkout_transactions - - belongs_to :member - belongs_to :checkout_balance - - is_impressionable - - before_validation(on: :create) do - # find balance otherwise create a new one - balance = CheckoutBalance.find_or_create_by!(member: member) - - if balance.save - self.checkout_balance = balance - else - throw :abort - end - end - - def send_confirmation! - # Generate token - digest = OpenSSL::Digest.new('sha1') - token = OpenSSL::HMAC.hexdigest(digest, ENV['CHECKOUT_TOKEN'], uuid) - - # Save token to card & mail confirmation link - return unless update(confirmation_token: token) - - Mailings::Checkout.confirmation_instructions( - self, - Rails.application.routes.url_helpers.confirmation_url(confirmation_token: token) - ).deliver_now - end -end diff --git a/app/models/checkout_product.rb b/app/models/checkout_product.rb deleted file mode 100644 index 10922e605..000000000 --- a/app/models/checkout_product.rb +++ /dev/null @@ -1,96 +0,0 @@ -#:nodoc: -class CheckoutProduct < ApplicationRecord - validates :name, presence: true - validates :category, presence: true - validates :price, presence: true, numericality: { greater_than_or_equal_to: 0 } - - has_one_attached :image - validate :content_type, unless: :skip_image_validation - attr_accessor :skip_image_validation - - def content_type - return if !image.attached? || image.content_type.in?(['image/jpeg', 'image/png']) - - errors.add(:image, - I18n.t('activerecord.errors.unsupported_content_type', type: image.content_type.to_s, - allowed: 'image/jpeg image/png')) - end - - enum category: { beverage: 1, chocolate: 2, savory: 3, additional: 4, liquor: 5 } - - def price=(price) - write_attribute(:price, price.to_s.tr(',', '.').to_f) - end - - before_update do - if name_changed? || category_changed? || price_changed? - record = CheckoutProduct.new - record.name = name - record.category = category - record.price = price - record.parent = id - - reload - update_columns(active: false) - - record.save - end - end - - def url - if image.attached? - return image.variant(thumbnail: '128x128^', gravity: 'center', - extent: '128x128') - end - - return nil if parent.nil? - - return CheckoutProduct.find_by(id: parent).url - end - - def children? - return true unless CheckoutProduct.find_by(parent: id).nil? - - return false - end - - def parents - return [] if parent.nil? - - return CheckoutProduct.where(id: parent).select(:id, :name, :price, :category, - :created_at) + CheckoutProduct.find_by(id: parent).parents - end - - def sales(year = nil) - year = year.blank? ? Date.today.study_year : year.to_i - - sales = CheckoutTransaction.where( - "created_at >= ? AND created_at < ? AND items LIKE '%- #{ id }\n%'", Date.to_date(year), Date.to_date(year + 1) - ).group(:items).count.map do |k, v| - { k => v } - end - - unless sales.nil? - count = sales.map do |hash| - hash.keys.first.count(id) * hash.values.first - end.inject(:+) - end - - return [{ self => count }] if parent.nil? - - return [{ self => count }] + CheckoutProduct.find_by(id: parent).sales(year) - end - - def self.last_version - CheckoutProduct.select { |product| !product.children? } # rubocop:disable Style/InverseMethods - end - - private - - def valid_image - return if image.present? || parent.present? - - errors.add(:image, - I18n.t('activerecord.errors.models.checkout_product.blank')) - end -end diff --git a/app/models/checkout_transaction.rb b/app/models/checkout_transaction.rb deleted file mode 100644 index 145816425..000000000 --- a/app/models/checkout_transaction.rb +++ /dev/null @@ -1,96 +0,0 @@ -#:nodoc: -class CheckoutTransaction < ApplicationRecord - validates :price, presence: true, numericality: { other_than: 0 } - validate :validate_sufficient_credit, :validate_payment_method, :validate_liquor_items - - belongs_to :checkout_card, optional: true - belongs_to :checkout_balance - - serialize :items, Array - - is_impressionable - - class_attribute :i18n_error_scope - self.i18n_error_scope = %i[activerecord errors models checkout_transaction attributes] - - before_validation do - # add items for a price - calculate_price if items.present? - - self.checkout_balance = checkout_card.checkout_balance if checkout_balance.nil? - end - - after_validation do - CheckoutBalance.where(id: checkout_balance.id).limit(1).update_all( - "balance = balance + #{ price }, updated_at = NOW()" - ) - end - - def validate_sufficient_credit - return unless price + checkout_balance.balance < 0 - - errors.add(:price, - I18n.t('price.insufficient_credit', - scope: i18n_error_scope)) - end - - def validate_payment_method - return unless payment_method.blank? && items.blank? - - errors.add(:payment_method, - I18n.t('payment_method.blank', - scope: i18n_error_scope)) - end - - def validate_liquor_items - return unless items.any? { |item| CheckoutProduct.find(item).liquor? } - - # only place you should use now, because liquor_time is without zone - if Time.now.before(Settings.liquor_time) && Rails.env.production? - errors.add(:items, - I18n.t('items.not_liquor_time', - scope: i18n_error_scope)) - end - - return unless checkout_balance.member.underage? - - errors.add(:items, - I18n.t('items.member_under_age', - scope: i18n_error_scope)) - end - - def calculate_price - self.price = -items.reduce(0) do |total, item_id| - item = CheckoutProduct.find(item_id) - total + item.price - end - price - end - - def price=(price) - write_attribute(:price, price.to_s.tr(',', '.').to_f) - end - - def products - return '-' if items.empty? - - counts = {} - items.each do |item| - unless counts.key?(CheckoutProduct.find_by(id: item).name) - counts[CheckoutProduct.find_by(id: item).name] = - 0 - end - counts[CheckoutProduct.find_by(id: item).name] += 1 - end - - strings = counts.map do |item, count| - if count > 1 - "#{ count }x #{ item }" - else - item.to_s - end - end - - strings.join(', ') - end -end diff --git a/app/models/member.rb b/app/models/member.rb index 9b5199843..25b950025 100644 --- a/app/models/member.rb +++ b/app/models/member.rb @@ -39,9 +39,6 @@ class Member < ApplicationRecord has_many :tags, dependent: :delete_all, autosave: true accepts_nested_attributes_for :tags, reject_if: :all_blank, allow_destroy: true - has_many :checkout_cards, dependent: :destroy - has_one :checkout_balance, dependent: :nullify - has_many :educations, dependent: :nullify has_many :studies, through: :educations accepts_nested_attributes_for :educations, @@ -374,7 +371,6 @@ def export export[:educations] = educations.pluck(:id) export[:participants] = participants.pluck(:id) export[:group_members] = group_members.pluck(:id) - export[:checkout_balance] = checkout_balance&.id export.compact @@ -424,11 +420,6 @@ def before_destroy logger.debug(JSON.parse(e.response.body)) rescue RestClient::NotFound logger.debug("Unable to delete Mailchimp user: user not found") - - # create transaction for emptying checkout_balance - if checkout_balance.present? && checkout_balance.balance != 0 - CheckoutTransaction.create(checkout_balance: checkout_balance, price: -checkout_balance.balance, payment_method: 'deleted') - end end # Perform an elfproef to verify the student_id diff --git a/app/models/payment.rb b/app/models/payment.rb index 4ea4ad10f..7155a39f9 100644 --- a/app/models/payment.rb +++ b/app/models/payment.rb @@ -124,24 +124,6 @@ def finalize! end self.message = I18n.t('success', scope: 'activerecord.errors.models.payment') - - when :checkout - # additional check if not already added checkout funds - return unless transaction_id.empty? - - # create a single transaction to update the checkoutbalance and mark the Payment as processed - Payment.transaction do - transaction = CheckoutTransaction.create!( - price: (amount - transaction_fee), - checkout_balance: CheckoutBalance.find_by!(member_id: member), - payment_method: payment_type - ) - - self.transaction_id = [transaction.id] - save! - - self.message = I18n.t('success', scope: 'activerecord.errors.models.payment') - end end end diff --git a/app/views/admin/home/index.html.haml b/app/views/admin/home/index.html.haml index 6b0904599..a55ea6652 100644 --- a/app/views/admin/home/index.html.haml +++ b/app/views/admin/home/index.html.haml @@ -5,8 +5,7 @@ .page .row - - .col-12.col-md-6 + .col-lg .card = link_to :members do .row.no-gutters @@ -18,7 +17,7 @@ %p.text-muted = I18n.t('admin.members.title') - .col-12.col-md-6 + .col-lg .card = link_to :activities do .row.no-gutters @@ -30,14 +29,14 @@ %p.text-muted = I18n.t('admin.activities.title') + .row // Checkout transactions used to be shown here. // That isn't in Koala anymore and was thus removed, // but we do not want to move the outstanding payment // card, so we leave this here as 'spacer' - .col-12.col-md-6 - .div + .col-lg - .col-12.col-md-6 + .col-lg .card = link_to :payments do .row.no-gutters @@ -50,7 +49,7 @@ = I18n.t('admin.front.outstanding_payments') .row - .col-lg-3.d-none.d-sm-block + .col-lg .card .card-header %i.fa.fa-fw.fa-graduation-cap @@ -63,10 +62,10 @@ %td= link_to I18n.t(code.downcase, scope: 'activerecord.attributes.study.names'), "/members?utf8=✓&search=studie:#{I18n.t(code.downcase, scope: 'activerecord.attributes.study.names').downcase.gsub( ' ', '-' )}" %td= count - .col-lg-5 + .col-lg .card .card-header - %i.fa.fa-fw.fa-shopping-cart + %i.fa.fa-fw.fa-credit-card = I18n.t('admin.front.activity_transactions_today') %table.table.table-striped.table-linked %tbody @@ -91,7 +90,8 @@ %tr %td.text-center %em= I18n.t('admin.front.no_transactions') - .col-lg-3 + + .col-lg .card .card-header %i.fa.fa-fw.fa-ticket-alt diff --git a/app/views/admin/settings/logs.html.haml b/app/views/admin/logs/index.html.haml similarity index 96% rename from app/views/admin/settings/logs.html.haml rename to app/views/admin/logs/index.html.haml index 272c95940..356bc67e2 100644 --- a/app/views/admin/settings/logs.html.haml +++ b/app/views/admin/logs/index.html.haml @@ -1,6 +1,5 @@ -- content_for(:page, 'settings') -- content_for(:subpage, 'logs') -- content_for(:title, "#{I18n.t('admin.navigation.settings')} | #{I18n.t('admin.navigation.impressions')}") +- content_for(:page, 'logs') +- content_for(:title, I18n.t('admin.navigation.impressions')) %section#content diff --git a/app/views/admin/payments/index.html.haml b/app/views/admin/payments/index.html.haml index 81484b41c..8a2b1ef2d 100644 --- a/app/views/admin/payments/index.html.haml +++ b/app/views/admin/payments/index.html.haml @@ -24,10 +24,10 @@ - activity.attendees.joins(:member).order('members.first_name', 'members.last_name').where(:paid => false).each do |participant| - if !participant.currency.nil? && participant.currency > 0 %tr{ :class => ('red' unless participant.currency.nil? || participant.paid), :data => { :'activities-id' => activity.id, :id => participant.id, :email => participant.member.email, :name => participant.member.name } } - %td= link_to "#{participant.member.name}", participant.member + %td{:style=> 'width: 100%;'}= link_to "#{participant.member.name}", participant.member - if !participant.currency.nil? - %td= link_to "#{number_to_currency(participant.currency, :unit => '€')}", participant.member + %td{:style=> 'text-align: right;'}= link_to "#{number_to_currency(participant.currency, :unit => '€')}", participant.member %td.buttons .btn-group @@ -104,7 +104,7 @@ %td %button.btn.btn-clipboard.btn-danger{ data: {'texturl': member_payment_whatsapp_path(member)} } %i.fa.fa-fw.fa-copy - = form_with url: transactions_export_path, method: :get, id: "export-transactions" do |f| + = form_with url: payment_transactions_export_path, method: :get, id: "export-transactions" do |f| .card .card-header %i.fas.fa-fw.fa-qrcode diff --git a/app/views/admin/apps/transactions.html.haml b/app/views/admin/transactions/index.html.haml similarity index 84% rename from app/views/admin/apps/transactions.html.haml rename to app/views/admin/transactions/index.html.haml index fe926181f..cf4ac65ed 100644 --- a/app/views/admin/apps/transactions.html.haml +++ b/app/views/admin/transactions/index.html.haml @@ -1,7 +1,5 @@ -- content_for(:page, 'apps') -- content_for(:subpage, 'Payments') - -- content_for(:title, "Apps | #{I18n.t('admin.navigation.transactions')}") +- content_for(:page, 'transactions') +- content_for(:title, I18n.t('admin.navigation.transactions')) %section#content @@ -51,9 +49,7 @@ = link_to transaction.member.name, transaction.member %td= I18n.t transaction.payment_type, scope: 'admin.transactions.payment_type' %td - - if transaction.transaction_type.downcase == 'checkouttransaction' - = I18n.t 'checkout', scope: 'activerecord.errors.models.payment.attributes' - - elsif transaction.transaction_type.downcase == 'activity' + - if transaction.transaction_type.downcase == 'activity' - transaction.activities.each do |activity| = link_to activity.name, activity, :class => 'inline' - else diff --git a/app/views/api/checkout/info.rabl b/app/views/api/checkout/info.rabl deleted file mode 100644 index 10284e0cf..000000000 --- a/app/views/api/checkout/info.rabl +++ /dev/null @@ -1,3 +0,0 @@ -object @card - -attributes :id, :uuid, :first_name, :balance diff --git a/app/views/api/checkout/products.rabl b/app/views/api/checkout/products.rabl deleted file mode 100644 index 22ac59ff8..000000000 --- a/app/views/api/checkout/products.rabl +++ /dev/null @@ -1,7 +0,0 @@ -collection @products - -attributes :id, :name, :category, :price - -node :image do |product| - "#{ ENV['KOALA_DOMAIN'] }#{ url_for(product.url) }" unless product.url.nil? -end diff --git a/app/views/api/checkout/recent.rabl b/app/views/api/checkout/recent.rabl deleted file mode 100644 index c2896639a..000000000 --- a/app/views/api/checkout/recent.rabl +++ /dev/null @@ -1,7 +0,0 @@ -collection @products - -attributes :id, :name, :category, :price - -node :image do |product| - "#{ ENV['KOALA_DOMAIN'] }#{ url_for(product.url) }" unless product.nil? -end diff --git a/app/views/layouts/partials/_navigation.html.haml b/app/views/layouts/partials/_navigation.html.haml index 58cbefcc1..243d26a4e 100644 --- a/app/views/layouts/partials/_navigation.html.haml +++ b/app/views/layouts/partials/_navigation.html.haml @@ -25,32 +25,20 @@ %span= I18n.t("admin.navigation.payments") %i.far.fa-money-bill-alt{:class => ('active' if current_page?(:payments))} - = link_to '', :class => 'list-group-item list-group-item-action', - 'data-toggle' => 'collapse', 'href' => '#sub-apps' do - %span= I18n.t("admin.navigation.apps") - %i.fa.fa-terminal{:class => ('active' if yield(:page) == 'apps')} - - .collapse.list-group#sub-apps{:class => ('show' if yield(:page) == 'apps')} - = link_to :paymenthandlers, :class => 'list-group-item list-group-item-action' do - %span= I18n.t("admin.navigation.transactions") - %i.fa.fa-caret-right{:class => ('active' if current_page?(:paymenthandlers))} - - = link_to '', :class => 'list-group-item list-group-item-action', - 'data-toggle' => 'collapse', 'href' => '#sub-settings' do + = link_to :transactions, :class => 'list-group-item list-group-item-action' do + %span= I18n.t("admin.navigation.transactions") + %i.fa.fa-history{:class => ('active' if current_page?(:transactions))} + + = link_to :settings, :class => 'list-group-item list-group-item-action' do %span= I18n.t("admin.navigation.settings") - %i.fas.fa-cog{:class => ('active' if yield(:page) == 'settings')} - - .collapse.list-group#sub-settings{:class => ('show' if yield(:page) == 'settings') } - = link_to :settings do - %span= I18n.t("admin.navigation.general") - %i.fas.fa-caret-right{:class => ('active' if current_page?(settings_path))} - - = link_to :logs_settings, :class => 'list-group-item list-group-item-action' do - %span= I18n.t("admin.navigation.impressions") - %i.fas.fa-caret-right{:class => ('active' if current_page?(logs_settings_path))} - - .d-md-none - = link_to destroy_user_session_path, 'data-method' => :delete do - %span= I18n.t("devise.sessions.new.sign_out") - %i.fa.fa-sign-out-alt - %span.icon-bg.bg-danger + %i.fas.fa-cog{:class => ('active' if current_page?(settings_path))} + + = link_to :logs, :class => 'list-group-item list-group-item-action' do + %span= I18n.t("admin.navigation.impressions") + %i.fas.fa-list-alt{:class => ('active' if current_page?(logs_path))} + + .d-md-none + = link_to destroy_user_session_path, 'data-method' => :delete do + %span= I18n.t("devise.sessions.new.sign_out") + %i.fa.fa-sign-out-alt + %span.icon-bg.bg-danger diff --git a/app/views/layouts/partials/_search_payments.html.haml b/app/views/layouts/partials/_search_payments.html.haml index 71b21b5c1..50df5df70 100644 --- a/app/views/layouts/partials/_search_payments.html.haml +++ b/app/views/layouts/partials/_search_payments.html.haml @@ -1,34 +1,31 @@ .page.page-item %section.panel.panel-default .card.card-body - = form_with url: paymenthandlers_path, method: 'get', local: true do |form| + = form_with url: transactions_path, method: 'get', local: true do |form| .input-group = form.text_field :search, placeholder: I18n.t('layouts.partials.search_payments.placeholder'), class: 'form-control', :autocomplete => 'off',value: params[:search] || "" .input-group-append .form-element - %button.btn.btn-info.dropdown-toggle{'data-toggle' => "dropdown", 'aria-haspopup' => 'true', 'aria-expanded'=>'false'}= I18n.t('admin.transactions.payment_type.title') + .btn.btn-info.dropdown-toggle{'data-toggle' => "dropdown", 'aria-haspopup' => 'true', 'aria-expanded'=>'false', 'tabindex'=>'0'}= I18n.t('admin.transactions.payment_type.title') .dropdown-menu.allow-focus - Payment.payment_types.keys.each_with_index.map { |transaction, index | [I18n.t(transaction, scope:'admin.transactions.payment_type'), index.to_s] }.each do |val,index| - .dropdown-item - .form-check - = form.check_box 'payment_type', {:multiple => true,checked: params.has_key?('payment_type') ? params['payment_type'].include?(index):false, :class =>'form-check-input'}, index, nil - .form-check-label= val + %label.dropdown-item + = form.check_box 'payment_type', {:multiple => true,checked: params.has_key?('payment_type') ? params['payment_type'].include?(index):false, :class =>'form-check-input'}, index, nil + .form-check-label= val .input-group-append - %button.btn.btn-info.dropdown-toggle{'data-toggle' => "dropdown", 'aria-haspopup' => 'true', 'aria-expanded'=>'false'}= I18n.t('admin.transactions.transaction_type.title') + .btn.btn-info.dropdown-toggle{'data-toggle' => "dropdown", 'aria-haspopup' => 'true', 'aria-expanded'=>'false', 'tabindex'=>'0'}= I18n.t('admin.transactions.transaction_type.title') .dropdown-menu.allow-focus - Payment.transaction_types.keys.each_with_index.map { |val, index | [I18n.t(val, scope:'admin.transactions.transaction_type'), index.to_s] }.each do |val,index| - .dropdown-item - .form-check - = form.check_box 'transaction_type', {:multiple => true,checked: params.has_key?('transaction_type') ? params['transaction_type'].include?(index):false, :class =>'form-check-input'}, index, nil - .form-check-label= val + %label.dropdown-item + = form.check_box 'transaction_type', {:multiple => true,checked: params.has_key?('transaction_type') ? params['transaction_type'].include?(index):false, :class =>'form-check-input'}, index, nil + .form-check-label= val .input-group-append - %button.btn.btn-info.dropdown-toggle{'data-toggle' => "dropdown", 'aria-haspopup' => 'true', 'aria-expanded'=>'false'}= I18n.t('admin.transactions.state.title') + .btn.btn-info.dropdown-toggle{'data-toggle' => "dropdown", 'aria-haspopup' => 'true', 'aria-expanded'=>'false', 'tabindex'=>'0'}= I18n.t('admin.transactions.state.title') .dropdown-menu.allow-focus - Payment.statuses.keys.each_with_index.map { |val, index | [I18n.t(val, scope:'admin.transactions.state'), index.to_s] }.each do |val,index| - .dropdown-item - .form-check - = form.check_box :status, {:id => val, checked: params.has_key?(:status) ? params[:status].include?(index):false,:multiple => true, :class =>'form-check-input'}, index, nil - .form-check-label= val + %label.dropdown-item + = form.check_box :status, {:id => val, checked: params.has_key?(:status) ? params[:status].include?(index):false,:multiple => true, :class =>'form-check-input'}, index, nil + .form-check-label= val .input-group-append = button_tag :class => "btn btn-primary" do %i.fa.fa-search diff --git a/app/views/mailings/checkout/confirmation_instructions.html.haml b/app/views/mailings/checkout/confirmation_instructions.html.haml deleted file mode 100644 index ccdf4f13c..000000000 --- a/app/views/mailings/checkout/confirmation_instructions.html.haml +++ /dev/null @@ -1,25 +0,0 @@ -%table{:cellpadding => "0", :cellspacing => "0", :style => "font-family: 'Helvetica Neue',Helvetica,Arial,sans-serif; box-sizing: border-box; font-size: 14px; margin: 0;", :width => "100%"} - - %tr{:style => "font-family: 'Helvetica Neue',Helvetica,Arial,sans-serif; box-sizing: border-box; font-size: 14px; margin: 0;"} - %td.content-block{:style => "font-family: 'Helvetica Neue',Helvetica,Arial,sans-serif; box-sizing: border-box; font-size: 14px; vertical-align: top; margin: 0; padding: 0 0 20px;", :valign => "top"} - = I18n.t("mailings.greeting") - %strong #{name}, - - %tr{:style => "font-family: 'Helvetica Neue',Helvetica,Arial,sans-serif; box-sizing: border-box; font-size: 14px; margin: 0;"} - %td.content-block{:style => "font-family: 'Helvetica Neue',Helvetica,Arial,sans-serif; box-sizing: border-box; font-size: 14px; vertical-align: top; margin: 0; padding: 0 0 20px;", :valign => "top"} - = I18n.t("mailings.checkout.confirmation_instructions") - - - %tr{:style => "font-family: 'Helvetica Neue',Helvetica,Arial,sans-serif; box-sizing: border-box; font-size: 14px; margin: 0;"} - %td.content-block.aligncenter{:align => "center", :style => "font-family: 'Helvetica Neue',Helvetica,Arial,sans-serif; box-sizing: border-box; font-size: 14px; vertical-align: top; margin: 0; padding: 0 0 20px;", :valign => "top"} - %a.btn-primary{:href => confirmation_url, :style => "font-family: 'Helvetica Neue',Helvetica,Arial,sans-serif; box-sizing: border-box; font-size: 14px; color: #FFF; text-decoration: none; line-height: 2em; font-weight: bold; text-align: center; cursor: pointer; display: inline-block; border-radius: 5px; background-color: #348eda; margin: 0; border-color: #348eda; border-style: solid; border-width: 10px 20px;"} - = I18n.t("mailings.checkout.confirm_card") - - - %tr{:style => "font-family: 'Helvetica Neue',Helvetica,Arial,sans-serif; box-sizing: border-box; font-size: 14px; margin: 0;"} - %td.content-block{:style => "font-family: 'Helvetica Neue',Helvetica,Arial,sans-serif; box-sizing: border-box; font-size: 14px; vertical-align: top; margin: 0; padding: 0 0 20px;", :valign => "top"} - = I18n.t("mailings.best_regards") - - %tr{:style => "font-family: 'Helvetica Neue',Helvetica,Arial,sans-serif; box-sizing: border-box; font-size: 14px; margin: 0;"} - %td.content-block{:style => "font-family: 'Helvetica Neue',Helvetica,Arial,sans-serif; box-sizing: border-box; font-size: 14px; vertical-align: top; margin: 0; padding: 0 0 20px;", :valign => "top"} - = I18n.t("mailings.signature") diff --git a/app/views/members/home/download.html.haml b/app/views/members/home/download.html.haml index b5cc0b602..e01819994 100644 --- a/app/views/members/home/download.html.haml +++ b/app/views/members/home/download.html.haml @@ -279,22 +279,6 @@ - else %td #{I18n.l activity.start_date} - #{I18n.l activity.end_date} - - if @transactions.length > 0 || @member.checkout_cards.length > 0 - %h2= I18n.t('members.home.edit.download.transactions') - - %table - %thead - %tr - %th= I18n.t('members.home.edit.download.general.date') - %th= I18n.t('members.home.edit.download.general.price') - %th= I18n.t('members.home.edit.download.general.products') - %tbody - - @transactions.each do |transaction| - %tr - %td= I18n.l transaction.created_at - %td= number_to_currency(transaction.price, :unit => '€', :negative_format => "%u%n -") - %td= transaction.products - %span.footer = I18n.t('members.home.edit.download.generated') = I18n.l(Time.now) diff --git a/app/views/members/payments/index.html.haml b/app/views/members/payments/index.html.haml index 6caacf8c5..fec75ec5e 100644 --- a/app/views/members/payments/index.html.haml +++ b/app/views/members/payments/index.html.haml @@ -83,43 +83,3 @@ - else %tr.card-body %td= I18n.t("members.payments.unpaid_activity.no_unpaid") - - -# .col-lg-6.col-12 - -# .card - -# = form_with :url => :mongoose, :local => true, :method=> :post, :class => 'form-validation', :id => "add_funds_form" do |f| - -# .card-header - -# .mb-2 - -# %i.fa.fa-fw.fa-fw.fa-shopping-cart - -# %span= I18n.t("activerecord.models.checkout_transactions") - -# .card-subtitle.text-muted - -# = I18n.t("members.payments.mongoose.subtitle") - -# .card-body - -# %table.table - -# %tbody - -# - @transactions.each do |transaction| - -# %tr - -# %td{ :colspan => 1 }= I18n.l transaction.created_at - -# %td.d-none.d-sm-table-cell= transaction.products - -# %td - -# = number_to_currency(transaction.price, :unit => '€') - -# - if transaction.price > 0 - -# %span.fa.fa-sort-asc.float-right - -# - else - -# %span.fa.fa-sort-desc.float-right - -# %td.d-table-cell.d-sm-table-cell - -# %tr - -# %td - -# %td - -# %td - -# %tr - -# %td.home_mongoose_form_element= I18n.t("members.payments.unpaid_activity.footer.transactioncosts") - -# %td.home_mongoose_form_element - -# = "€#{String(@transaction_costs)}" - -# %td.home_mongoose_form_element - -# %tr - -# %td.home_mongoose_form_element - -# .ideal-mongoose= f.select :bank, options_for_select(Payment::ideal_issuers), {} - -# %td.home_mongoose_form_element - -# = f.text_field :amount, :placeholder => I18n.t('members.payments.mongoose.credit'), :pattern => '^\d+(\.|\,)\d{2}$', 'data-toggle' => 'tooltip', :required => '' - -# %td.home_mongoose_form_element - -# = f.submit I18n.t('members.payments.mongoose.upgrade'), class: "btn btn-success btn-sm", type: "submit" diff --git a/bin/test_all_mails.rb b/bin/test_all_mails.rb index 13d7f25ce..3409b7e42 100755 --- a/bin/test_all_mails.rb +++ b/bin/test_all_mails.rb @@ -2,8 +2,6 @@ return unless Rails.env.development? -Mailings::Checkout.confirmation_instructions(CheckoutCard.first, 'placeholder') - Mailings::Devise.confirmation_instructions(User.second, 'placeholder') Mailings::Devise.activation_instructions(User.second, 'placeholder') diff --git a/config/routes.rb b/config/routes.rb index 74df2f5e8..81dca115a 100644 --- a/config/routes.rb +++ b/config/routes.rb @@ -3,7 +3,7 @@ constraints subdomain: ['intro', 'intro.dev'] do scope module: 'public' do - get '/', to: 'home#index', as: 'public' + get '/', to: 'home#index', as: 'public' post '/', to: 'home#create' end end @@ -15,15 +15,14 @@ get '/activities/69420', to: redirect('/CommITCrowd.jpg') - get 'edit', to: 'home#edit', as: :users_edit - post 'edit', to: 'home#update' - delete 'authorized_applications/:id', to: 'home#revoke', as: :authorized_applications + get 'edit', to: 'home#edit', as: :users_edit + post 'edit', to: 'home#update' + delete 'authorized_applications/:id', to: 'home#revoke', as: :authorized_applications get 'download', to: 'home#download' get 'member/payments', to: 'payments#index', as: :member_payments - post 'mongoose', to: 'payments#add_funds' post 'pay_activities', to: 'payments#pay_activities' resources :activities, only: [:index, :show] do @@ -35,8 +34,8 @@ root 'admin/home#index' # No double controllers - get 'admin/home', to: redirect('/') - get 'members/home', to: redirect('/') + get 'admin/home', to: redirect('/') + get 'members/home', to: redirect('/') # Devise routes devise_for :users, path: '', skip: [:registrations], controllers: { @@ -46,29 +45,28 @@ } # create account using a member's email - get 'sign_up', to: 'users/registrations#new', as: :new_registration - post 'sign_up', to: 'users/registrations#create' + get 'sign_up', to: 'users/registrations#new', as: :new_registration + post 'sign_up', to: 'users/registrations#create' # update account with password after receiving invite - get 'activate', to: 'users/registrations#edit', as: :new_member_confirmation - post 'activate', to: 'users/registrations#update', as: :new_member_confirm + get 'activate', to: 'users/registrations#edit', as: :new_member_confirmation + post 'activate', to: 'users/registrations#update', as: :new_member_confirm # update password from member options - get 'passwordchange', to: 'users/password_change#edit', as: :password_change - patch 'passwordchange', to: 'users/password_change#update' + get 'passwordchange', to: 'users/password_change#edit', as: :password_change + patch 'passwordchange', to: 'users/password_change#update' scope module: 'public' do - get 'status(/:token)', to: 'status#edit' - post 'status', to: 'status#update' - post 'status/destroy', to: 'status#destroy' + get 'status(/:token)', to: 'status#edit' + post 'status', to: 'status#update' + post 'status/destroy', to: 'status#destroy' end scope module: 'admin' do resources :members do - get 'payment_whatsapp' + get 'payment_whatsapp' patch 'force_email_change' - post 'email/:type', to: 'members#send_email', as: :mail - patch 'set_card_disabled/:uuid', to: 'members#set_card_disabled', as: 'set_card_disabled' + post 'email/:type', to: 'members#send_email', as: :mail collection do get 'search' @@ -87,8 +85,8 @@ scope 'payments' do get '/', to: 'payments#index', as: "payments" get 'whatsapp/:member_id', to: 'payments#whatsapp_redirect', as: 'payment_whatsapp_redirect' - get 'transactions', to: 'payments#update_transactions' - get 'transactions_export', to: 'payments#export_payments' + get 'transactions', to: 'payments#update_transactions', as: 'payment_transactions' + get 'transactions_export', to: 'payments#export_payments', as: 'payment_transactions_export' end resources :posts, only: [:index, :show, :create, :update, :destroy] @@ -99,23 +97,16 @@ resources :settings, only: [:index, :create] do collection do - get 'logs' patch 'profile', to: 'settings#profile' end end - scope 'apps' do - get 'payments', to: 'apps#transactions', as: 'paymenthandlers' - get 'checkout', to: 'apps#checkout' - - # json checkout urls - patch 'cards', to: 'checkout_products#activate_card' - patch 'transactions', to: 'checkout_products#change_funds' + scope 'transactions' do + get '/', to: 'transactions#index', as: 'transactions' + end - resources :checkout_products, only: [:index, :show, :create, :update], path: 'products' do - patch :flip, action: :flip_active - match :flip, action: :flip_active, via: [:patch] - end + scope 'logs' do + get '/', to: 'logs#index', as: 'logs' end # sidekiq web interface @@ -146,27 +137,11 @@ scope 'hook' do get 'payment/:token', to: 'webhook#payment_redirect', as: 'payment_redirect' - post 'mollie', to: 'webhook#mollie_hook', as: 'mollie_hook' + post 'mollie', to: 'webhook#mollie_hook', as: 'mollie_hook' get 'mailchimp/:token', to: 'webhook#mailchimp_confirm_callback', as: 'mailchimp_confirm' post 'mailchimp/:token', to: 'webhook#mailchimp', as: 'mailchimp' end - - # NOTE: legacy implementation for checkout without oauth - scope 'checkout' do - get 'card', to: 'checkout#info' - get 'recent', to: 'checkout#recent' - post 'card', to: 'checkout#create' - get 'confirmation', to: 'checkout#confirm' - - get 'products', to: 'checkout#products' - post 'transaction', to: 'checkout#purchase' - end - - scope 'internal' do - get 'member_by_id', to: 'internal#member_by_id' - get 'member_by_studentid', to: 'internal#member_by_studentid' - end end end end diff --git a/db/seeds.rb b/db/seeds.rb index 04728b1a6..a33369c83 100644 --- a/db/seeds.rb +++ b/db/seeds.rb @@ -88,7 +88,6 @@ # Load files in seperate seed files require Rails.root.join('db', 'seeds', 'members.rb') require Rails.root.join('db', 'seeds', 'users.rb') -require Rails.root.join('db', 'seeds', 'checkout.rb') require Rails.root.join('db', 'seeds', 'groups.rb') require Rails.root.join('db', 'seeds', 'activities.rb') require Rails.root.join('db', 'seeds', 'payments.rb') diff --git a/db/seeds/checkout.rb b/db/seeds/checkout.rb deleted file mode 100644 index e9faa4b01..000000000 --- a/db/seeds/checkout.rb +++ /dev/null @@ -1,59 +0,0 @@ -require Rails.root.join('db', 'seeds', 'members.rb') - -# Create checkout cards will automatically create balances -puts '-- Creating checkout balances and cards' -Member.all.sample(30).each do |member| - Faker::Number.within(range: 0..2).times do - CheckoutCard.create( - uuid: Faker::Number.hexadecimal(digits: 8), - active: Faker::Boolean.boolean(true_ratio: 0.9), - member_id: member.id - ) - end -end - -puts '-- Giving away free money' -CheckoutCard.all.each do |card| - CheckoutTransaction.create( - checkout_card_id: card.id, - price: 9.00, - payment_method: %w[Gepind Contant].sample, - created_at: Faker::Time.between(from: Time.now - 1.days, to: card.member.join_date) - ) -end - -puts '-- Creating products' -5.times do - # Create a few food products - CheckoutProduct.create!( - name: Faker::Food.unique.dish, - category: Faker::Number.within(range: 2..4), - price: Faker::Number.between(from: 0.50, to: 4.0), - skip_image_validation: true - ) -end - -2.times do - # Create a few alcoholic products - CheckoutProduct.create( - name: Faker::Beer.name, - category: 5, - price: Faker::Number.between(from: 1.0, to: 3.0), - skip_image_validation: true - ) -end - -puts '-- Creating checkout transactions' -CheckoutCard.all.each do |card| - Faker::Number.within(range: 0..10).times do - checkout_products = CheckoutProduct.all - checkout_products.reject(&:liquor?) if card.member.underage? - - CheckoutTransaction.create( - checkout_card_id: card.id, - items: checkout_products.sample(Faker::Number.within(range: 1..3)).map(&:id), - payment_method: 'Verkoop', - created_at: Faker::Time.between(from: Time.now, to: card.member.join_date) - ) - end -end diff --git a/db/seeds/payments.rb b/db/seeds/payments.rb index a618513cd..ae1f9889d 100644 --- a/db/seeds/payments.rb +++ b/db/seeds/payments.rb @@ -6,11 +6,11 @@ Member.all.sample(30).each do |member| 15.times do - transactiontype = Faker::Number.within(range: 0..1) + transactiontype = 1 # either ideal or pin (see app/models/payment.rb) paymenttype = Faker::Number.within(range: 0.0..1.0) < 0.5 ? 0 : 3 status = Faker::Number.within(range:0..2) - if transactiontype == 1 && status == 0 + if status == 0 participants = Participant.where(member:member).where.not(activity:[nil,1]).select{|p| p.currency != nil}.sample(Faker::Number.within(range:1..6)) participants.map {|p|p.update(paid:true)} transaction_id = participants.map{|p| p.activity.id} diff --git a/doc/api_readme2.md b/doc/api_readme2.md index 79c877c7b..4b867b16f 100644 --- a/doc/api_readme2.md +++ b/doc/api_readme2.md @@ -34,174 +34,4 @@ Content-Type → application/json; charset=utf-8 ] ``` -## Participant - - -## Checkout -All checkout endpoints require a secret called `token` declared in the configuration of [.env](/sample.env). A generic response because of this would be a forbidden response meaning that the secret does not correspond with the secret of koala. -```json -HTTP/1.1 403 FORBIDDEN -Content-Type → application/json; charset=utf-8 -``` -Below are the endpoints that can be used for checkout. - - - -##### Retrieve products -
-GET /api/checkout/products HTTP/1.1
-Host → koala.svsticky.nl
-
-+ token          :string (required)
-
- -```json -HTTP/1.1 200 OK -Content-Type → application/json; charset=utf-8 - -[ - { - "id": 98, - "name": "7up", - "category": 1, - "price": "0.4", - "image": "https://koala.svsticky.nl/images/checkout_products/7/original.png?1433681363" - }, - { - "id": 100, - "name": "Coca Cola regular", - "category": 1, - "price": "0.53", - "image": "https://koala.svsticky.nl/images/checkout_products/1/original.png?1433681225" - } -] -``` - - - -##### Information for card -
-GET /api/checkout/card HTTP/1.1
-Host → koala.svsticky.nl
-
-+ token          :string (required)
-+ uuid           :string (required) - unique identifier of the OV-card
-
- -```json -HTTP/1.1 200 OK -Content-Type → application/json; charset=utf-8 - -{ - "id": 9, - "uuid": "EDD411C4", - "first_name": "Martijn", - "balance": "4.15" -} -``` - -```json -# card with that specific uuid not found -HTTP/1.1 404 NOT FOUND -Content-Type → application/json; charset=utf-8 -``` - - - -##### Create a new card and add to member -
-POST /api/checkout/card HTTP/1.1
-Host → koala.svsticky.nl
-
-+ token          :string (required)
-+ student        :string (required) - student id as known by koala
-+ uuid           :string (required)
-+ description    :string
-
- -```json -HTTP/1.1 201 CREATED -Content-Type → application/json; charset=utf-8 - -{ - "id": 9, - "uuid": "EDD411C4", - "first_name": "Martijn", - "balance": "0.0" -} -``` - -```json -# Student could not be found, make sure the student id is correct -HTTP/1.1 404 NOT FOUND -Content-Type → application/json; charset=utf-8 -``` - -```json -# This uuid is already registered to some student -HTTP/1.1 409 CONFLICT -Content-Type → application/json; charset=utf-8 -``` - - - -##### Create a new transaction -
-POST /api/checkout/transaction HTTP/1.1
-Host → koala.svsticky.nl
-
-+ token          :string (required)
-+ uuid           :string (required)
-+ items          :array  (required) - array with item ids
-
- -```json -HTTP/1.1 201 CREATED -Content-Type → application/json; charset=utf-8 - -{ - "uuid": "EDD411C4", - "first_name": "Martijn", - "balance": "0.9", - "created_at": "2016-02-06T10:33:50.382+01:00" -} -``` - -```json -# Card is not yet activated -HTTP/1.1 401 UNAUTHORIZED -Content-Type → application/json; charset=utf-8 -``` - -```json -# One of the items in your array is not found or -# there is no card with the specified uuid -HTTP/1.1 404 NOT FOUND -Content-Type → application/json; charset=utf-8 -``` - -```json -HTTP/1.1 413 REQUEST ENTITY TOO LARGE -Content-Type → application/json; charset=utf-8 - -{ - "message": "insufficient funds", - "balance": "2.9", - "items": [ - 1, - 2, - 2 - ], - "costs": "-4.6" -} -``` - -```json -# Not allowed to buy alcohol at the moment -HTTP/1.1 406 NOT ACCEPTABLE -Content-Type → application/json; charset=utf-8 - -{ - "message": "alcohol allowed at 16:00" -} -``` +## Participant \ No newline at end of file From 8c93b1335763819ae0239e8ac2687a7ed346ccd1 Mon Sep 17 00:00:00 2001 From: Mervin de Jong Date: Sat, 14 Sep 2024 16:46:27 +0200 Subject: [PATCH 2/3] Removed dangling route from routes.rb and payments.js --- app/javascript/src/admin/payments.js | 65 ---------------------------- config/routes.rb | 1 - 2 files changed, 66 deletions(-) diff --git a/app/javascript/src/admin/payments.js b/app/javascript/src/admin/payments.js index 3b51a0a25..e0be6b6ae 100644 --- a/app/javascript/src/admin/payments.js +++ b/app/javascript/src/admin/payments.js @@ -18,13 +18,6 @@ $(document).on("ready page:load turbolinks:load", function () { }, ); - $(".input-group#transaction_dates #update_transactions button").bind( - "click", - function () { - getCheckoutTransactions($(this)); - }, - ); - //Update search $("input#search").on("keyup", function () { var query = new RegExp($(this).val(), "i"); @@ -63,61 +56,3 @@ function getWhatsappText(url) { async: false, }).responseText; } - -//Requests all checkout transactions for a given date -function getCheckoutTransactions(button) { - var start_date = $("#pin-total-date").val(); - - $.ajax({ - url: "/payments/transactions", - type: "GET", - data: { - start_date: start_date, - }, - }) - .done(function (data, status) { - //Find and clear table - var table = $("#transactions").find("tbody"); - var total = 0.0; - $(table).find("tr").remove(); - - // Bind json data to copy button - $("#copy_transactions button").attr( - "data-clipboard-text", - JSON.stringify(data), - ); - - //Fill table if not empty - if (data.length == 0) { - table.append( - `${I18n.t( - "admin.payment.no_transactions", - )}`, - ); - toastr.warning(I18n.t("admin.payment.not_found")); - } else { - $.each(data, function (key, t) { - let value = parseFloat(t.price); - total += value; - t.price = "€" + value.toFixed(2); - if (t.price.indexOf("-") > 0) t.price = "-€" + t.price.substring(2); - table.append( - '' + - t.name + - "" + - t.price + - "" + - t.date + - "", - ); - }); - toastr.success(I18n.t("admin.payment.found")); - } - $("#pin-total-result").text("€" + total.toFixed(2)); - }) - .fail(function () { - toastr.error(I18n.t("admin.payment.no_update")); - }); -} diff --git a/config/routes.rb b/config/routes.rb index 81dca115a..04d8cda67 100644 --- a/config/routes.rb +++ b/config/routes.rb @@ -85,7 +85,6 @@ scope 'payments' do get '/', to: 'payments#index', as: "payments" get 'whatsapp/:member_id', to: 'payments#whatsapp_redirect', as: 'payment_whatsapp_redirect' - get 'transactions', to: 'payments#update_transactions', as: 'payment_transactions' get 'transactions_export', to: 'payments#export_payments', as: 'payment_transactions_export' end From 91651168af53b24049888073439c0008c589b3de Mon Sep 17 00:00:00 2001 From: Mervin de Jong Date: Sat, 14 Sep 2024 19:05:51 +0200 Subject: [PATCH 3/3] Prevent close filter menu's on click in transaction page --- app/views/layouts/partials/_search_payments.html.haml | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/app/views/layouts/partials/_search_payments.html.haml b/app/views/layouts/partials/_search_payments.html.haml index 50df5df70..6ba63d687 100644 --- a/app/views/layouts/partials/_search_payments.html.haml +++ b/app/views/layouts/partials/_search_payments.html.haml @@ -9,21 +9,21 @@ .btn.btn-info.dropdown-toggle{'data-toggle' => "dropdown", 'aria-haspopup' => 'true', 'aria-expanded'=>'false', 'tabindex'=>'0'}= I18n.t('admin.transactions.payment_type.title') .dropdown-menu.allow-focus - Payment.payment_types.keys.each_with_index.map { |transaction, index | [I18n.t(transaction, scope:'admin.transactions.payment_type'), index.to_s] }.each do |val,index| - %label.dropdown-item + %label.dropdown-item{:onclick=>"event.stopPropagation()"} = form.check_box 'payment_type', {:multiple => true,checked: params.has_key?('payment_type') ? params['payment_type'].include?(index):false, :class =>'form-check-input'}, index, nil .form-check-label= val .input-group-append .btn.btn-info.dropdown-toggle{'data-toggle' => "dropdown", 'aria-haspopup' => 'true', 'aria-expanded'=>'false', 'tabindex'=>'0'}= I18n.t('admin.transactions.transaction_type.title') .dropdown-menu.allow-focus - Payment.transaction_types.keys.each_with_index.map { |val, index | [I18n.t(val, scope:'admin.transactions.transaction_type'), index.to_s] }.each do |val,index| - %label.dropdown-item + %label.dropdown-item{:onclick=>"event.stopPropagation()"} = form.check_box 'transaction_type', {:multiple => true,checked: params.has_key?('transaction_type') ? params['transaction_type'].include?(index):false, :class =>'form-check-input'}, index, nil .form-check-label= val .input-group-append .btn.btn-info.dropdown-toggle{'data-toggle' => "dropdown", 'aria-haspopup' => 'true', 'aria-expanded'=>'false', 'tabindex'=>'0'}= I18n.t('admin.transactions.state.title') .dropdown-menu.allow-focus - Payment.statuses.keys.each_with_index.map { |val, index | [I18n.t(val, scope:'admin.transactions.state'), index.to_s] }.each do |val,index| - %label.dropdown-item + %label.dropdown-item{:onclick=>"event.stopPropagation()"} = form.check_box :status, {:id => val, checked: params.has_key?(:status) ? params[:status].include?(index):false,:multiple => true, :class =>'form-check-input'}, index, nil .form-check-label= val .input-group-append