Skip to content

Commit

Permalink
Campaigns controller part 1 (#141)
Browse files Browse the repository at this point in the history
  • Loading branch information
ganhongyao authored Oct 14, 2022
2 parents e08485f + fd247a9 commit 60d1c9e
Show file tree
Hide file tree
Showing 22 changed files with 197 additions and 23 deletions.
16 changes: 11 additions & 5 deletions backend/app/controllers/campaigns_controller.rb
Original file line number Diff line number Diff line change
@@ -1,8 +1,8 @@
# frozen_string_literal: true

class CampaignsController < ApplicationController
before_action :authenticate_admin!
before_action :set_campaign, only: %i[show update destroy]
before_action :authenticate_admin!, except: %i[index show]
before_action :set_campaign, only: %i[show admin_show update destroy]

wrap_parameters format: :json,
include: %w[name description promisedAmount start end primaryDonorId
Expand All @@ -12,27 +12,33 @@ def index
@campaigns = Campaign.all
end

def admin_index
@campaigns = Campaign.all
end

def show; end

def admin_show; end

def create
@campaign = Campaign.create!(campaign_params)

add_success_message "Campaign \"#{@campaign.name}\" successfully created!"
render :show, status: :created, location: @campaign
render :response, status: :created, location: @campaign
end

def update
@campaign.update!(campaign_params)

add_success_message "Campaign \"#{@campaign.name}\" successfully updated!"
render :show, status: :ok, location: @campaign
render :response, status: :ok, location: @campaign
end

def destroy
@campaign.destroy!

add_success_message "Campaign \"#{@campaign.name}\" successfully deleted!"
render :show, status: :ok, location: @campaign
render :response, status: :ok, location: @campaign
end

private
Expand Down
19 changes: 18 additions & 1 deletion backend/app/models/campaign.rb
Original file line number Diff line number Diff line change
Expand Up @@ -18,14 +18,31 @@ class Campaign < ApplicationRecord
validates :description, presence: true, allow_blank: false
validates :start, presence: true
validates :end, comparison: { greater_than: :start }
validates :campaign_charities, presence: true
validates :campaign_charities, length: { minimum: 1, maximum: 5 }
validates :promised_amount, final: true
validates :coupon_denomination, final: true
validates :image,
content_type: { in: ['image/png', 'image/jpg', 'image/jpeg'],
message: 'is mot of a supported file type. Please upload a PNG, JPG or JPEG file.' },
size: { less_than: 1.megabytes, message: 'must be less than 1MB.' }

def donation_breakdown
primary_donor_amount = num_redeemed_coupons * coupon_denomination
secondary_donors_amount = secondary_donations.sum(&:amount)
total_amount = (primary_donor_amount + secondary_donors_amount).to_f
primary_donor_fraction = primary_donor_amount / total_amount
secondary_donors_fraction = secondary_donors_amount / total_amount

{ primary_donor_amount: primary_donor_amount,
primary_donor_fraction: primary_donor_fraction,
secondary_donors_amount: secondary_donors_amount,
secondary_donors_fraction: secondary_donors_fraction }
end

def num_redeemed_coupons
coupons.count(&:redeemed?)
end

private

def num_coupons
Expand Down
14 changes: 14 additions & 0 deletions backend/app/models/campaign_charity.rb
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,20 @@ class CampaignCharity < ApplicationRecord
belongs_to :campaign
belongs_to :charity
has_many :secondary_donations, dependent: :destroy
has_many :coupons, through: :secondary_donations

validates :giving_sg_url, presence: true, allow_blank: false, format: { with: URI::DEFAULT_PARSER.make_regexp }

def donation_breakdown
primary_donor_amount = coupons.count * campaign.coupon_denomination
secondary_donors_amount = secondary_donations.sum(&:amount)
total_amount = (primary_donor_amount + secondary_donors_amount).to_f
primary_donor_fraction = primary_donor_amount / total_amount
secondary_donors_fraction = secondary_donors_amount / total_amount

{ primary_donor_amount: primary_donor_amount,
primary_donor_fraction: primary_donor_fraction,
secondary_donors_amount: secondary_donors_amount,
secondary_donors_fraction: secondary_donors_fraction }
end
end
2 changes: 1 addition & 1 deletion backend/app/models/coupon.rb
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@ class Coupon < ApplicationRecord
NUM_ALPHANUMERIC_CHARS_IN_TOKEN = 6

belongs_to :campaign
has_one :secondary_donation, required: false, dependent: nil
has_one :secondary_donation, required: false, dependent: :nullify

validates :url_token, presence: true, uniqueness: true
validates :denomination, presence: true, numericality: { only_integer: true, greater_than: 0 }
Expand Down
7 changes: 7 additions & 0 deletions backend/app/views/campaign_charities/_base.json.jbuilder
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
# frozen_string_literal: true

json.id campaign_charity.id
json.charity do
json.id campaign_charity.charity.id
end
json.givingSgUrl campaign_charity.giving_sg_url
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
# frozen_string_literal: true

json.partial! 'campaign_charities/base', campaign_charity: campaign_charity
json.charity do
json.partial! 'charities/list', charity: campaign_charity.charity
end
4 changes: 4 additions & 0 deletions backend/app/views/campaign_charities/_donation.json.jbuilder
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
# frozen_string_literal: true

json.partial! 'campaign_charities/campaign_charity', campaign_charity: campaign_charity
json.partial! 'secondary_donations/breakdown', donation_breakdown: campaign_charity.donation_breakdown
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
# frozen_string_literal: true

json.partial! 'campaign_charities/campaign_charity', campaign_charity: campaign_charity
json.partial! 'secondary_donations/breakdown', donation_breakdown: campaign_charity.donation_breakdown

json.attributes!.delete('givingSgUrl')
19 changes: 19 additions & 0 deletions backend/app/views/campaigns/_base.json.jbuilder
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
# frozen_string_literal: true

json.id campaign.id
json.name campaign.name
json.description campaign.description
json.promisedAmount campaign.promised_amount
json.start campaign.start
json.end campaign.end
json.imageBase64 encoded_file_data_url(campaign.image)

json.charities campaign.campaign_charities do |campaign_charity|
json.partial! 'campaign_charities/base', campaign_charity: campaign_charity
end

json.primaryDonor do
json.partial! 'primary_donors/primary_donor', primary_donor: campaign.primary_donor
end

json.interestId campaign.interest_id
13 changes: 13 additions & 0 deletions backend/app/views/campaigns/admin_index.json.jbuilder
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
# frozen_string_literal: true

json.array! @campaigns do |campaign|
json.id campaign.id
json.name campaign.name
json.promisedAmount campaign.promised_amount
json.start campaign.start
json.end campaign.end
json.primaryDonor do
json.id campaign.primary_donor.id
json.name campaign.primary_donor.name
end
end
16 changes: 16 additions & 0 deletions backend/app/views/campaigns/admin_show.json.jbuilder
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
# frozen_string_literal: true

json.partial! 'campaigns/base', campaign: @campaign

json.donations do
json.partial! 'secondary_donations/breakdown', donation_breakdown: @campaign.donation_breakdown
end

json.charities [] # ignore the charities from the base partial, since Jbuilder merges instead of overwriting
json.charities do
json.array! @campaign.campaign_charities, partial: 'campaign_charities/donation', as: :campaign_charity
end

json.coupons do
json.array! @campaign.coupons, partial: 'coupons/list', as: :coupon
end
17 changes: 16 additions & 1 deletion backend/app/views/campaigns/index.json.jbuilder
Original file line number Diff line number Diff line change
@@ -1,3 +1,18 @@
# frozen_string_literal: true

json.array! @campaigns, partial: 'campaigns/campaign', as: :campaign
json.array! @campaigns do |campaign|
json.id campaign.id
json.name campaign.name
json.description campaign.description
json.imageBase64 encoded_file_data_url(campaign.image)

json.charities do
json.array! campaign.charities, partial: 'charities/list', as: :charity
end

json.donations do
json.partial! 'secondary_donations/breakdown', donation_breakdown: campaign.donation_breakdown
end

json.couponsRedeemedCount campaign.num_redeemed_coupons
end
3 changes: 3 additions & 0 deletions backend/app/views/campaigns/response.json.jbuilder
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
# frozen_string_literal: true

json.partial! 'campaigns/base', campaign: @campaign
11 changes: 10 additions & 1 deletion backend/app/views/campaigns/show.json.jbuilder
Original file line number Diff line number Diff line change
@@ -1,3 +1,12 @@
# frozen_string_literal: true

json.partial! 'campaigns/campaign', campaign: @campaign
json.partial! 'campaigns/base', campaign: @campaign

json.donations do
json.partial! 'secondary_donations/breakdown', donation_breakdown: @campaign.donation_breakdown
end

json.charities [] # ignore the charities from the base partial, since Jbuilder merges instead of overwriting
json.charities do
json.array! @campaign.campaign_charities, partial: 'campaign_charities/donation_public', as: :campaign_charity
end
4 changes: 4 additions & 0 deletions backend/app/views/charities/_list.json.jbuilder
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
# frozen_string_literal: true

json.partial! 'charities/minimal', charity: charity
json.logoBase64 encoded_file_data_url(charity.logo)
4 changes: 4 additions & 0 deletions backend/app/views/charities/_minimal.json.jbuilder
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
# frozen_string_literal: true

json.id charity.id
json.name charity.name
6 changes: 6 additions & 0 deletions backend/app/views/coupons/_base.json.jbuilder
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
# frozen_string_literal: true

json.id coupon.id
json.urlToken coupon.url_token
json.denomination coupon.denomination
json.campaignId coupon.campaign_id
16 changes: 16 additions & 0 deletions backend/app/views/coupons/_list.json.jbuilder
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
# frozen_string_literal: true

json.partial! 'coupons/base', coupon: coupon

if coupon.secondary_donation.present?
json.secondaryDonation do
json.partial! 'secondary_donations/secondary_donation', secondary_donation: coupon.secondary_donation
end

json.charity do
json.partial! 'charities/minimal', charity: coupon.secondary_donation.campaign_charity.charity
end
else
json.secondaryDonation nil
json.charity nil
end
11 changes: 11 additions & 0 deletions backend/app/views/secondary_donations/_breakdown.json.jbuilder
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
# frozen_string_literal: true

json.primaryDonor do
json.amount donation_breakdown[:primary_donor_amount]
json.fraction donation_breakdown[:primary_donor_fraction]
end

json.secondaryDonors do
json.amount donation_breakdown[:secondary_donors_amount]
json.fraction donation_breakdown[:secondary_donors_fraction]
end
Original file line number Diff line number Diff line change
@@ -1,16 +1,6 @@
# frozen_string_literal: true

json.id secondary_donation.id
json.couponId secondary_donation.coupon_id
json.amount secondary_donation.amount

if secondary_donation.coupon
json.coupon do
json.partial! 'coupons/coupon', coupon: secondary_donation.coupon
end
else
json.coupon nil
end

json.charity do
json.partial! 'charities/charity', charity: secondary_donation.campaign_charity.charity
end
json.campaignCharityId secondary_donation.campaign_charity_id
10 changes: 9 additions & 1 deletion backend/config/routes.rb
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,15 @@
sessions: 'auth/sessions'
}

resources :campaigns
resources :campaigns do
collection do
get :admin_index
end

member do
get 'admin_show'
end
end

resources :charities

Expand Down
2 changes: 1 addition & 1 deletion frontend/types/donations.ts
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,7 @@ export type SecondaryDonationData = {
id: number;
couponId: Nullable<number>;
amount: number;
campaignsCharityId: number;
campaignCharityId: number;
};

export type SecondaryDonationPostData = WithoutId<SecondaryDonationData>;

0 comments on commit 60d1c9e

Please sign in to comment.