Skip to content

Commit

Permalink
payment and forms refined with required fields
Browse files Browse the repository at this point in the history
  • Loading branch information
consmas committed Aug 19, 2024
1 parent 0f16fce commit 29bd949
Show file tree
Hide file tree
Showing 27 changed files with 413 additions and 102 deletions.
28 changes: 28 additions & 0 deletions app/controllers/admin/payment_settings_controller.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,28 @@
class Admin::PaymentSettingsController < Admin::BaseController

layout 'admin'

def index
@payment_settings = PaymentSetting.all
end

def edit
@payment_setting = PaymentSetting.find(params[:id])
end

def update
@payment_setting = PaymentSetting.find(params[:id])
if @payment_setting.update(payment_setting_params)
redirect_to admin_payment_settings_path, notice: 'Payment setting updated successfully.'
else
render :edit
end
end

private

def payment_setting_params
params.require(:payment_setting).permit(:key, :value)
end
end

55 changes: 37 additions & 18 deletions app/controllers/bookings_controller.rb
Original file line number Diff line number Diff line change
@@ -1,32 +1,37 @@
class BookingsController < ApplicationController
before_action :authenticate_user!
before_action :set_venue, except: [:index, :new, :create]
before_action :set_venue, only: [:new, :create, :index]
before_action :set_booking, only: [:edit, :update, :destroy]
before_action :set_venues, only: [:new, :edit]

layout 'admin', if: -> { current_user.admin? }

def index
@bookings = if @venue
@venue.bookings.order(:booking_date)
else
Booking.includes(:venue, :user).order(:booking_date)
Booking.includes(:venue, :user).order(:booking_date) if current_user.admin?
end
end

def new
@booking = Booking.new
@venues = Venue.all
@booked_dates = Booking.where(venue_id: params[:venue_id]).pluck(:booking_date).map(&:to_s)
end

@booking = Booking.new
end

def create
@booking = Booking.new(booking_params)
@booking.venue = @venue
@booking.user = current_user

if @booking.save
redirect_to all_bookings_path, notice: 'Booking was successfully created.'
# Initiate the payment via Flutterwave
result = FlutterwavePaymentService.new(@booking).initiate_payment
if result[:success]
redirect_to result[:payment_link], allow_other_host: true
else
flash[:error] = "Payment initialization failed: #{result[:error]}"
redirect_to @venue
end
else
set_venues
render :new
end
end
Expand All @@ -37,7 +42,6 @@ def update
if @booking.update(booking_params)
redirect_to all_bookings_path, notice: 'Booking was successfully updated.'
else
set_venues
render :edit
end
end
Expand All @@ -46,23 +50,38 @@ def destroy
@booking.destroy
redirect_to all_bookings_path, notice: 'Booking was successfully deleted.'
end

def payment_success
transaction_id = params[:transaction_id]

response = HTTParty.get(
"https://api.flutterwave.com/v3/transactions/#{transaction_id}/verify",
headers: {
"Authorization" => "Bearer #{@api_key}"
}
)

if response['status'] == 'success'
@booking.update(status: 'Confirmed')
redirect_to @booking, notice: 'Payment was successful. Booking confirmed.'
else
flash[:error] = "Payment verification failed. Please contact support."
redirect_to @booking
end
end

private

def set_venues
@venues = Venue.all
def set_venue
@venue = Venue.find_by(id: params[:venue_id])
end

def set_booking
@booking = Booking.find(params[:id])
end

def set_venues
@venues = Venue.all
end

def booking_params
params.require(:booking).permit(:booking_date, :user_id, :venue_id)
end
end
end

20 changes: 16 additions & 4 deletions app/controllers/memberships_controller.rb
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,8 @@ class MembershipsController < ApplicationController
before_action :set_membership, only: [:show, :edit, :update, :destroy, :flutterwave_payment, :payment_success, :payment_cancel]
before_action :authorize_user!, only: [:edit, :update, :destroy]

layout 'admin', if: -> { current_user.admin? }
# Apply the layout based on the user role
layout :determine_layout

def index
@memberships = current_user.admin? ? Membership.all : current_user.memberships
Expand Down Expand Up @@ -95,9 +96,15 @@ def set_membership

def membership_params
permitted_params = [
:first_name, :last_name, :phone, :email, :partner_first_name,
:partner_last_name, :partner_phone, :partner_email, :pastor_name,
:partner_pastor_name, :ministry, :partner_ministry, :lab_results
:first_name, :last_name, :phone, :email,
:partner_first_name, :partner_last_name, :partner_phone, :partner_email,
:male_birth_date, :female_birth_date,
:male_place_of_birth, :female_place_of_birth,
:male_residential_address, :female_residential_address,
:male_born_again, :female_born_again,
:male_born_again_date, :female_born_again_date,
:male_born_again_reason, :female_born_again_reason,
:male_passport_picture, :female_passport_picture
]

permitted_params << :status if current_user.admin?
Expand All @@ -110,5 +117,10 @@ def authorize_user!
redirect_to memberships_path, alert: 'You are not authorized to perform this action.'
end
end

# Determines which layout to use based on the user's role
def determine_layout
current_user.admin? ? 'admin' : 'application'
end
end

4 changes: 2 additions & 2 deletions app/controllers/venues_controller.rb
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@ class VenuesController < ApplicationController
before_action :set_venue, only: [:show, :edit, :update, :destroy]

layout 'admin', if: -> { current_user.admin? }

def index
@venues = Venue.all
end
Expand Down Expand Up @@ -48,7 +48,7 @@ def set_venue
end

def venue_params
params.require(:venue).permit(:name, :location_id)
params.require(:venue).permit(:name, :location_id, :price)
end
end

2 changes: 2 additions & 0 deletions app/helpers/admin/payment_settings_helper.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
module Admin::PaymentSettingsHelper
end
5 changes: 5 additions & 0 deletions app/models/payment_setting.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
# app/models/payment_setting.rb
class PaymentSetting < ApplicationRecord
validates :key, presence: true, uniqueness: true
validates :value, presence: true
end
1 change: 1 addition & 0 deletions app/models/venue.rb
Original file line number Diff line number Diff line change
Expand Up @@ -4,4 +4,5 @@ class Venue < ApplicationRecord

validates :name, presence: true
validates :location, presence: true
validates :price, presence: true, numericality: { greater_than_or_equal_to: 0 }
end
23 changes: 12 additions & 11 deletions app/services/flutterwave_payment_service.rb
Original file line number Diff line number Diff line change
@@ -1,26 +1,27 @@
# app/services/flutterwave_payment_service.rb
class FlutterwavePaymentService
def initialize(membership)
@membership = membership
def initialize(booking)
@booking = booking
@venue = booking.venue
@api_key = "FLWSECK_TEST-5888bc2d2331e6137f56fb83be4484f7-X" # Replace with your actual secret key
end

def initiate_payment
payment_data = {
tx_ref: SecureRandom.hex(10), # Unique transaction reference
amount: 100.0, # Replace with your desired amount logic
amount: @venue.price, # Use the venue's price as the amount
currency: 'GHS',
redirect_url: payment_success_url,
payment_options: 'card, mobilemoneyghana',
customer: {
email: @membership.email,
phonenumber: @membership.phone,
name: "#{@membership.first_name} #{@membership.last_name}"
email: @booking.user.email,
phonenumber: @booking.user.phone, # Assuming user model has a phone attribute
name: @booking.user.full_name # Assuming user model has a full_name method
},
customizations: {
title: 'Membership Registration Payment',
description: 'Payment for membership registration',
logo: 'https://yourwebsite.com/logo.png' # Replace with your logo URL
title: 'Venue Booking Payment',
description: "Payment for booking at #{@venue.name}",
logo: 'https://flcms-99e59f7f5d8a.herokuapp.com/assets/logo-img-1-5be75ec22e5c2c62cb5e1d2161924c07fae0db0619b6c635d0d0d40b04d5b05c.png' # Replace with your logo URL
}
}

Expand All @@ -43,7 +44,7 @@ def initiate_payment
private

def payment_success_url
Rails.application.routes.url_helpers.payment_success_membership_url(@membership, host: Rails.application.config.action_mailer.default_url_options[:host])
Rails.application.routes.url_helpers.payment_success_booking_url(@booking, host: Rails.application.config.action_mailer.default_url_options[:host])
end
end
end

13 changes: 13 additions & 0 deletions app/views/admin/payment_settings/edit.html.erb
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
<!-- app/views/admin/payment_settings/edit.html.erb -->
<h1>Payment Settings</h1>

<%= form_with(model: @payment_setting, url: admin_payment_setting_path, local: true) do |form| %>
<div class="mb-3">
<%= form.label :value, "Membership Registration Fee (GHC)" %>
<%= form.text_field :value, class: "form-control" %>
</div>

<div class="actions">
<%= form.submit "Update Settings", class: "btn btn-primary" %>
</div>
<% end %>
29 changes: 29 additions & 0 deletions app/views/admin/payment_settings/index.html.erb
Original file line number Diff line number Diff line change
@@ -0,0 +1,29 @@
<!-- app/views/admin/payment_settings/index.html.erb -->
<h1>Payment Settings</h1>

<% if @payment_settings.present? %>
<table class="table table-striped">
<thead>
<tr>
<th>Key</th>
<th>Value</th>
<th>Actions</th>
</tr>
</thead>
<tbody>
<% @payment_settings.each do |setting| %>
<tr>
<td><%= setting.key %></td>
<td><%= setting.value %></td>
<td>
<%= link_to 'Edit', edit_admin_payment_setting_path(setting), class: 'btn btn-secondary btn-sm' %>
</td>
</tr>
<% end %>
</tbody>
</table>
<% else %>
<p>No payment settings found.</p>
<% end %>

<%= link_to 'Back', admin_root_path, class: 'btn btn-secondary mt-3' %>
4 changes: 2 additions & 2 deletions app/views/layouts/admin.html.erb
Original file line number Diff line number Diff line change
Expand Up @@ -80,12 +80,12 @@
<img src="https://github.com/mdo.png" alt="mdo" width="24" height="24" class="rounded-circle">
</a>
<ul class="dropdown-menu text-small shadow">
<li><a class="dropdown-item" href="#">New project...</a></li>
<li><a class="dropdown-item" href="#">Settings</a></li>
<li><%= link_to "Settings", admin_payment_settings_path, class: "dropdown-item" %></li>
<li><a class="dropdown-item" href="#">Profile</a></li>
<li><hr class="dropdown-divider"></li>
<li><%= link_to "Sign out", destroy_user_session_path, method: :delete, class: "dropdown-item" %></li>
</ul>

</div>
</nav>
<% end %>
Expand Down
77 changes: 57 additions & 20 deletions app/views/layouts/application.html.erb
Original file line number Diff line number Diff line change
@@ -1,22 +1,59 @@
<!DOCTYPE html>
<html>
<head>
<meta name="viewport" content="width=device-width, initial-scale=1">
<meta charset="utf-8">
<meta name="description" content="Your application description">

<title>FLMS</title>
<%= csrf_meta_tags %>
<%= csp_meta_tag %>

<link rel="icon" href="/icon.svg" type="image/svg+xml">
<link rel="apple-touch-icon" href="/icon.png">
<%= stylesheet_link_tag "application", "data-turbo-track": "reload" %>
<%= javascript_importmap_tags %>
<script src="https://checkout.flutterwave.com/v3.js"></script>
</head>

<body>
<%= yield %>
</body>
<html lang="en">
<head>
<meta charset="utf-8">
<meta name="viewport" content="width=device-width, initial-scale=1">
<meta name="description" content="Your application description">

<title>FLMS</title>
<%= csrf_meta_tags %>
<%= csp_meta_tag %>

<link rel="icon" href="/icon.svg" type="image/svg+xml">
<link rel="apple-touch-icon" href="/icon.png">
<%= stylesheet_link_tag "application", "data-turbo-track": "reload" %>

<!-- Bootstrap CSS -->
<link href="https://cdn.jsdelivr.net/npm/bootstrap@5.3.0/dist/css/bootstrap.min.css" rel="stylesheet" integrity="sha384-9ndCyUaIbzAi2FUVXJi0CjmCapSmO7SnpJef0486qhLnuZ2cdeRhO02iuK6FUUVM" crossorigin="anonymous">
<link href="https://cdn.jsdelivr.net/npm/bootstrap-icons/font/bootstrap-icons.css" rel="stylesheet">

<link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/bootstrap-datepicker/1.9.0/css/bootstrap-datepicker.min.css">

<%= javascript_importmap_tags %>
<script src="https://checkout.flutterwave.com/v3.js"></script>

<script src="https://cdn.jsdelivr.net/npm/@rails/ujs@7.0.4/lib/assets/compiled/rails-ujs.js"></script>
</head>

<body>
<% if user_signed_in? && current_user.user? %>
<!-- Navbar for Users -->
<nav class="navbar navbar-expand-lg navbar-light bg-light">
<div class="container-fluid">
<a class="navbar-brand" href="#">FLMS</a>
<button class="navbar-toggler" type="button" data-bs-toggle="collapse" data-bs-target="#navbarNav" aria-controls="navbarNav" aria-expanded="false" aria-label="Toggle navigation">
<span class="navbar-toggler-icon"></span>
</button>
<div class="collapse navbar-collapse" id="navbarNav">
<ul class="navbar-nav me-auto mb-2 mb-lg-0">
<li class="nav-item">
<%= link_to 'Home', home_path, class: 'nav-link' %>
</li>
<li class="nav-item">
<%= link_to 'Register Membership', new_membership_path, class: 'nav-link' %>
</li>
</ul>
<ul class="navbar-nav">
<li class="nav-item">
<%= link_to 'Sign out', destroy_user_session_path, method: :delete, class: 'nav-link' %>
</li>
</ul>
</div>
</div>
</nav>
<% end %>

<%= yield %> <!-- Main content of the page will be rendered here -->

</body>
</html>
Loading

0 comments on commit 29bd949

Please sign in to comment.