Commit 850d609a authored by Alexandre Friquet's avatar Alexandre Friquet
Browse files

Collaborating club can renew subscription for new season: refs #90.

parent b5df8eef
......@@ -164,8 +164,8 @@ GEM
ffi (1.9.18)
fitvidsjs_rails (1.1.3)
railties (>= 3.1)
font-awesome-rails (4.7.0.2)
railties (>= 3.2, < 5.2)
font-awesome-rails (4.7.0.4)
railties (>= 3.2, < 6.0)
fullcalendar-rails (3.4.0.0)
jquery-rails (>= 4.0.5, < 5.0.0)
jquery-ui-rails (>= 5.0.2)
......
......@@ -44,15 +44,29 @@ form#search_contacts_form {
}
}
li.subscription {
span {
padding: 0 0.5em;
&.billed { @include button-color($oligaa-green); }
&.not-billed { @include button-color; }
&.platform-number { font: caption;}
&.activities {
display: none;
aside#subscriptions {
div {
padding: 0 1em;
a.expendable {
display: block;
}
ul {
padding: 0.5em 0;
li.subscription {
span {
padding: 0 0.5em;
&.billed { @include button-color($oligaa-green); }
&.not-billed { @include button-color; }
&.platform-number { font: caption;}
&.activities {
display: none;
}
}
i.fa-info-circle:hover + span.activities { display: block;}
}
}
}
i.fa-info-circle:hover + span.activities { display: block;}
}
......@@ -96,9 +96,12 @@ class MembersController < ApplicationController
@disabled_performances = @member.performances.disabled
if @member.collaborating_club?
@internal_subscriptions = @member.subscriptions
@seasoned_internal_subscriptions = Season.all_for(@internal_subscriptions, :created_at)
@external_subscriptions = Subscription.for_performances(@member.performance_ids) - @internal_subscriptions
@seasoned_external_subscriptions = Season.all_for(@external_subscriptions, :created_at)
elsif @member.collaborating_medicosocial_org?
@internal_subscriptions = Subscription.of_medicosocial_org(@member).by_adherent_name
@seasoned_internal_subscriptions = Season.all_for(@internal_subscriptions, :created_at)
end
else
authorize
......
......@@ -24,7 +24,7 @@ class SubscriptionsController < ApplicationController
include AuthorizationsHelper
before_action :set_member
before_action :set_subscription, only: [:edit, :update, :destroy, :card, :toggle_billing]
before_action :set_subscription, only: [:edit, :update, :destroy, :card, :toggle_billing, :renew]
before_action :authorize_member, except: [:destroy, :toggle_billing, :card]
before_action :authorize, only: [:destroy, :toggle_billing]
before_action :set_medico_social_orgs, except: [:destroy, :card, :toggle_billing]
......@@ -37,7 +37,7 @@ class SubscriptionsController < ApplicationController
def create
@subscription = @member.subscriptions.build(subscription_params).tap do |subscription|
subscription.build_adherent(adherent_params)
subscription.adherent = Adherent.available_for_current_season(adherent_params)
end
if @subscription.save
......@@ -90,6 +90,12 @@ class SubscriptionsController < ApplicationController
render layout: nil
end
def renew
old_subscription = @subscription
@subscription = old_subscription.dup
@subscription.performance_ids = old_subscription.performance_ids
end
def destroy
if @subscription
@subscription.destroy
......
......@@ -137,4 +137,11 @@ module LinksHelper
custom_link 'fa-toggle-on', 'Activer', path, version, options
end
def custom_redo_link(path, version = :normal, options = {})
options[:class] ||= []
options[:class] << 'primary'
custom_link 'fa-repeat', 'Renouveler', path, version, options
end
end
......@@ -30,6 +30,17 @@ class Adherent < ApplicationRecord
before_validation :cleanup_medicosocial_org
def self.available_for_current_season(params)
current_season = Season.new(Date.today)
adherent = Adherent.find(params[:id]) if params[:id].present?
if adherent && !adherent.subscriptions.map(&:season).map(&:shorten).uniq.include?(current_season.shorten)
adherent
else
params.delete(:id)
Adherent.new(params)
end
end
def name
"#{first_name} #{last_name}"
end
......
......@@ -32,11 +32,11 @@ class Season
Settings.instance.reload.season_birthdate || self.default_birthdate
end
def self.all_for(items)
def self.all_for(items, date_field=:begin_at)
result = {}
items.each do |item|
year = item.begin_at.year
if item.begin_at >= Season.birthdate.change(year: year)
year = item.send(date_field).year
if item.send(date_field)>= Season.birthdate.change(year: year)
(result["Saison #{year.to_s}-#{(year+1).to_s}"] ||= []) << item
else
(result["Saison #{(year-1).to_s}-#{year.to_s}"] ||= []) << item
......
......@@ -37,27 +37,40 @@
Nos adhérents
<span><%= Statistics::Pass::Unit.new(@member).label %></span>
</h2>
<ul id="internal">
<% @internal_subscriptions.each do |subscription| %>
<li class="subscription">
<%= custom_print_card_link card_member_subscription_path(@member, subscription, format: :pdf), :short, class: %w(tight) %>
<%- if admin? %>
<%= custom_edit_link edit_member_subscription_path(@member, subscription), :short, class: %w(tight) %>
<%= custom_delete_link member_subscription_path(@member, subscription), :short, class: %w(tight) %>
<%- end %>
<%= internal_subscription_label(subscription) %>
</li>
<div id="internal">
<%- @seasoned_internal_subscriptions.each do |season, subscriptions| %>
<% season_label = season.downcase.gsub(/\s/, '_') + "_int" %>
<%= toggle_link "#{ season } (#{ subscriptions.length })", "##{season_label}" %>
<ul id="<%= season_label %>" style="display:none;">
<% subscriptions.each do |subscription| %>
<li class="subscription">
<%= custom_print_card_link card_member_subscription_path(@member, subscription, format: :pdf), :short, class: %w(tight) %>
<%= custom_redo_link renew_member_subscription_path(@member, subscription), :short, class: %w(tight) %>
<%- if admin? %>
<%= custom_edit_link edit_member_subscription_path(@member, subscription), :short, class: %w(tight) %>
<%= custom_delete_link member_subscription_path(@member, subscription), :short, class: %w(tight) %>
<%- end %>
<%= internal_subscription_label(subscription) %>
</li>
<%- end %>
</ul>
<%- end if @internal_subscriptions %>
</ul>
</div>
<%- unless @member.collaborating_medicosocial_org? %>
<h2>Adhérents extérieurs</h2>
<ul id="external">
<% @external_subscriptions.each do |subscription| %>
<li class="subscription">
<%= external_subscription_label(subscription, @member) %>
</li>
<%- end if @external_subscriptions %>
</ul>
<h2>Adhérents extérieurs</h2>
<div id="external">
<%- @seasoned_external_subscriptions.each do |season, subscriptions| %>
<% season_label = season.downcase.gsub(/\s/, '_') + "_ext" %>
<%= toggle_link "#{ season } (#{ subscriptions.length })", "##{season_label}" %>
<ul id="<%= season_label %>" style="display:none;">
<% subscriptions.each do |subscription| %>
<li class="subscription">
<%= external_subscription_label(subscription, @member) %>
</li>
<%- end %>
</ul>
<%- end if @external_subscriptions %>
</div>
<%- end %>
</aside>
<%- end %>
......@@ -28,7 +28,7 @@
<%= f.fields_for :adherent do |a| %>
<%= a.input :last_name %>
<%= a.input :first_name %>
<%= a.input :born_on, as: :string %>
<%= a.input :born_on, as: :date_picker %>
<%= a.input :permit_number %>
<%= a.association :medico_social_org, collection: @medico_social_orgs, include_blank: "Autre", required: true %>
<%= a.input :other_medicosocial_org, required: true %>
......
<%
# OLIGAA - Stands for "Outil en Ligne d'Information et de Gestion des Activités
# des Associations" which is an online tool for associations to manage news,
# actors and activities.
# Copyright (C) 2010-2018 Comité Départemental du Sport Adapté de la Gironde (CDSA
# 33) <contact@cdsa33.org>
#
# This file is part of OLIGAA.
#
# OLIGAA is free software: you can redistribute it and/or modify
# it under the terms of the GNU Affero General Public License as
# published by the Free Software Foundation, either version 3 of the
# License, or (at your option) any later version.
#
# OLIGAA is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
# GNU Affero General Public License for more details.
#
# You should have received a copy of the GNU Affero General Public License
# along with OLIGAA. If not, see <http://www.gnu.org/licenses/>.
%>
<% title 'Renouvellement adhésion' %>
<div class="card-block">
<h1><%= yield :title %></h1>
<p class="AdminCard-globalActions">
<%= custom_list_link member_path(@member) %>
</p>
<%= render 'form' %>
</div>
......@@ -60,6 +60,7 @@ Rails.application.routes.draw do
get :option, on: :collection
get :card, on: :member
patch :toggle_billing, on: :member
get :renew, on: :member
end
end
resources :member_groups, :except => [:index] do
......
......@@ -24,9 +24,14 @@ require 'rails_helper'
feature "Manage subscriptions" do
context "as an admin" do
before { login_as_admin }
before do
Timecop.freeze(Date.new(2017,10,15))
login_as_admin
end
after { Timecop.freeze }
scenario "I can delete one" do
scenario "I can delete one", :js do
collaborating_clubs_mg = create :member_group
asso = create :member, member_groups: [collaborating_clubs_mg]
@settings.platform_collaborating_clubs << collaborating_clubs_mg
......@@ -35,19 +40,22 @@ feature "Manage subscriptions" do
subscription = create :subscription, adherent: adherent, performances: [perf], member_id: asso.id
visit member_path(asso)
within "aside#subscriptions li", text: "Jean Dupont" do
click_delete_link
within "aside#subscriptions div#internal" do
click_link "Saison 2017-2018"
within "li", text: "Jean Dupont" do
click_delete_link
end
end
expect(current_path).to eq member_path(asso)
expect(page).to have_content "L'adhésion a bien été supprimée."
within "aside#subscriptions ul#internal" do
expect(page).not_to have_content "Jean Dupont"
within "aside#subscriptions div#internal" do
expect(page).not_to have_content "Saison 2017-2018"
end
end
context "regarding edition" do
scenario "I can edit one" do
scenario "I can edit one", :js do
collaborating_clubs_mg = create :member_group
asso = create :member, member_groups: [collaborating_clubs_mg]
@settings.platform_collaborating_clubs << collaborating_clubs_mg
......@@ -56,8 +64,11 @@ feature "Manage subscriptions" do
subscription = create :subscription, adherent: adherent, performances: [perf], member_id: asso.id
visit member_path(asso)
within "aside#subscriptions li", text: "Jean Dupont" do
click_edit_link
within "aside#subscriptions div#internal" do
click_link "Saison 2017-2018"
within "li", text: "Jean Dupont" do
click_edit_link
end
end
expect(current_path).to eq edit_member_subscription_path(asso, subscription)
......@@ -68,7 +79,8 @@ feature "Manage subscriptions" do
expect(current_path).to eq member_path(asso)
expect(page).to have_content "L'adhésion a bien été mise à jour."
within "aside#subscriptions ul#internal" do
within "aside#subscriptions div#internal" do
click_link "Saison 2017-2018"
expect(page).not_to have_content "Jean Dupont"
expect(page).to have_content "Jean Dupond"
end
......@@ -302,7 +314,10 @@ feature "Manage subscriptions" do
end
context "as a collaborating club" do
before { login_as_collaborating_club }
before do
Timecop.freeze(Date.new(2017,10,15))
login_as_collaborating_club
end
let(:athle) { create :activity, title: "Athlétisme" }
let(:swim) { create :activity, title: "Natation" }
......@@ -356,9 +371,12 @@ feature "Manage subscriptions" do
expect(current_path).to eq member_path(@member)
expect(page).to have_content "L'adhésion de Jean-Charles Dupont a bien été créée."
within "aside#subscriptions ul#internal li", text: "Jean-Charles Dupont" do
find("i.fa-info-circle").hover
expect(page).to have_selector("span.activities", text: "Mon asso (Athlétisme)")
within "aside#subscriptions div#internal" do
click_link "Saison 2017-2018"
within "li", text: "Jean-Charles Dupont" do
find("i.fa-info-circle").hover
expect(page).to have_selector("span.activities", text: "Mon asso (Athlétisme)")
end
end
@settings.platform_medicosocial_orgs.clear
......@@ -388,9 +406,12 @@ feature "Manage subscriptions" do
expect(current_path).to eq member_path(@member)
expect(page).to have_content "L'adhésion de Jean-Charles Dupont a bien été créée."
within "aside#subscriptions ul#internal li", text: "Jean-Charles Dupont" do
find("i.fa-info-circle").hover
expect(page).to have_selector("span.activities", text: "Mon asso (Athlétisme)")
within "aside#subscriptions div#internal" do
click_link "Saison 2017-2018"
within "li", text: "Jean-Charles Dupont" do
find("i.fa-info-circle").hover
expect(page).to have_selector("span.activities", text: "Mon asso (Athlétisme)")
end
end
end
......@@ -425,7 +446,7 @@ feature "Manage subscriptions" do
end
end
scenario "I can see internal and external subscriptions" do
scenario "I can see internal and external subscriptions", :js do
athle = create :activity, title: "Athlétisme"
parapente = create :activity, title: "Parapente"
voile = create :activity, title: "Voile"
......@@ -441,45 +462,54 @@ feature "Manage subscriptions" do
external_subscription = create :subscription, adherent: external_adherent, performances: [perf1, perf3], member_id: external_club.id
visit member_path(@member)
within "aside#subscriptions" do
within "ul#internal" do
expect(page).to have_selector("li", text: "3311/1718/042 Jean Dupont")
within "aside#subscriptions div#internal" do
click_link "Saison 2017-2018"
within "li", text: "3311/1718/042 Jean Dupont" do
find("i.fa-info-circle").hover
expect(page).to have_selector("span.activities", text: "Mon asso (Parapente), Les Mouettes (Voile)")
end
within "ul#external" do
within "li", text: "Pascal Durand (Les Mouettes) →" do
expect(page).to have_content "[Athlétisme] Lundi de 18h00 à 20h00"
expect(page).not_to have_content "[Voile]"
end
end
within "aside#subscriptions div#external" do
click_link "Saison 2017-2018"
within "li", text: "Pascal Durand (Les Mouettes) →" do
expect(page).to have_content "[Athlétisme] Lundi"
expect(page).not_to have_content "[Voile]"
end
end
end
scenario "I cannot delete any" do
scenario "I cannot delete any", :js do
athle = create :activity, title: "Athlétisme"
adherent = build :adherent, last_name: "Dupont", first_name: "Jean"
perf = create :performance, member: @member, activity: athle
subscription = create :subscription, adherent: adherent, performances: [perf], member_id: @member.id
visit member_path(@member)
within "aside#subscriptions li", text: "Jean Dupont" do
expect(page).not_to have_link "Supprimer"
within "aside#subscriptions div#internal" do
click_link "Saison 2017-2018"
within "li", text: "Jean Dupont" do
expect(page).not_to have_link "Supprimer"
end
end
end
scenario "I cannot edit any" do
scenario "I cannot edit any", :js do
athle = create :activity, title: "Athlétisme"
adherent = build :adherent, last_name: "Dupont", first_name: "Jean"
perf = create :performance, member: @member, activity: athle
subscription = create :subscription, adherent: adherent, performances: [perf], member_id: @member.id
visit member_path(@member)
within "aside#subscriptions li", text: "Jean Dupont" do
expect(page).not_to have_link "Éditer"
within "aside#subscriptions div#internal" do
click_link "Saison 2017-2018"
within "li", text: "Jean Dupont" do
expect(page).not_to have_link "Éditer"
end
end
end
scenario "I can print the licence paper" do
scenario "I can print the licence paper", :js do
@member.update_attribute(:affiliation_number, "3369")
@settings.platform_collaborating_clubs << @member.member_groups
athle = create :activity, title: "Athlétisme"
......@@ -503,8 +533,11 @@ feature "Manage subscriptions" do
end
visit member_path(@member)
within "aside#subscriptions li", text: "Jean Dupont" do
expect(page).to have_link "Imprimer carte"
within "aside#subscriptions div#internal" do
click_link "Saison 2017-2018"
within "li", text: "Jean Dupont" do
expect(page).to have_link "Imprimer carte"
end
end
end
......@@ -520,7 +553,7 @@ feature "Manage subscriptions" do
end
end
scenario "I can see the billing status of any one" do
scenario "I can see the billing status of any one", :js do
perf1 = create :performance, member: @member
perf2 = create :performance, member: @member
jean_dupont = build :adherent, first_name: "Jean", last_name: "Dupont"
......@@ -529,7 +562,8 @@ feature "Manage subscriptions" do
not_billed_subscription = create :subscription, adherent: pascal_durand, performances: [perf1, perf2], member_id: @member.id, billed_at: nil
visit member_path(@member)
within "ul#internal" do
within "aside#subscriptions div#internal" do
click_link "Saison 2017-2018"
within "li", text: "Jean Dupont" do
expect(page).to have_selector("span.billed")
end
......@@ -539,12 +573,60 @@ feature "Manage subscriptions" do
end
end
scenario "I can renew one", :js do
medico_social_orgs_group = create :member_group
msi = create :member, member_groups: [medico_social_orgs_group], name: "IME Untel"
@settings.platform_medicosocial_orgs << medico_social_orgs_group
athle = create :activity, title: "Athlétisme"
adherent = build :adherent, last_name: "Dupont", first_name: "Jean", born_on: "14/07/1989", permit_number: "123456", medico_social_org: msi
@member.update_attribute(:name, "Club partenaire")
perf = create :performance, member: @member, activity: athle
subscription = create :subscription, adherent: adherent, performances: [perf], member_id: @member.id
Timecop.travel(Date.new(2018,10,15))
visit member_path(@member)
within "aside#subscriptions div#internal" do
click_link "Saison 2017-2018"
within "ul#saison_2017-2018_int li", text: "Jean Dupont" do
click_link "Renouveler"
end
end
expect(current_path).to eq renew_member_subscription_path(@member, subscription)
within "form" do
expect(page).to have_field("Nom", with: "Dupont")
expect(page).to have_field("Prénom", with: "Jean")
expect(page).to have_field("Date de naissance", with: "14/07/1989")
expect(page).to have_field("N° licence", with: "123456")
expect(page).to have_select("Structure médico-sociale", selected: 'IME Untel')
expect(page).to have_checked_field("Club partenaire - [Athlétisme] Lundi")
click_create_button
end
expect(current_path).to eq member_path(@member)
expect(page).to have_content "L'adhésion de Jean Dupont a bien été créée."
within "aside#subscriptions div#internal" do
click_link "Saison 2018-2019"
within "ul#saison_2018-2019_int" do
expect(page).to have_selector("li", text: "Jean Dupont")
end
click_link "Saison 2017-2018"
within "ul#saison_2017-2018_int" do
expect(page).to have_selector("li", text: "Jean Dupont")
end
end
end
end
context "as a collaborating medicosocial org" do
before { login_as_collaborating_medicosocial_org }
before do
Timecop.freeze(Date.new(2017,10,15))
login_as_collaborating_medicosocial_org
end
after { Timecop.return }
scenario "I can list susbscriptions of my patients" do
scenario "I can list susbscriptions of my patients", :js do
@settings.platform_collaborating_medicosocial_orgs << @member.member_groups
medicosocial_orgs_mg = create :member_group
@settings.platform_medicosocial_orgs << medicosocial_orgs_mg
......@@ -563,19 +645,19 @@ feature "Manage subscriptions" do
create :subscription, adherent: pascal_durand, performances: [perf_mouettes], member_id: mouettes.id
visit member_path(@member)
within "aside#subscriptions" do
within "ul#internal" do
within "li", text: "Jean Dupont" do
expect(page).to have_selector("span.activities", text: "USG (Athlétisme), Les Mouettes (Surf)")
end
within "li", text: "Pascal Durand" do
expect(page).to have_selector("span.activities", text: "Les Mouettes (Surf)")
end
within "h2", text: "Nos adhérents" do
expect(page).to have_selector("span", text: "(1 multi, 1 mono sur 2)")
end
within "aside#subscriptions div#internal" do
click_link "Saison 2017-2018"
within "li", text: "Jean Dupont" do
find("i.fa-info-circle").hover
expect(page).to have_selector("span.activities", text: "USG (Athlétisme), Les Mouettes (Surf)")
end
within "h2", text: "Nos adhérents" do
expect(page).to have_selector("span", text: "(1 multi, 1 mono sur 2)")
within "li", text: "Pascal Durand" do
find("i.fa-info-circle").hover
expect(page).to have_selector("span.activities", text: "Les Mouettes (Surf)")
end
end
end
......
......@@ -79,4 +79,79 @@ RSpec.describe Adherent, type: :model do
expect(adherent.medico_social_org_name).to eq "IME two"
end
end
describe "scopes" do
context ".available_for_current_season" do
let(:params) {
{
first_name: "Jean",
last_name: "Dupont",
born_on: "14/07/1989",
permit_number: "123456",
medico_social_org_id: nil,
other_medicosocial_org: nil
}
}
context "adherent does not exist" do
it "returns a just built one" do
# Given
# When
result = Adherent.available_for_current_season(params)
# Then
expect(result).to be_a Adherent
expect(result).not_to be_persisted
end
end
context "adherent alreaday exists" do
let!(:existing_adherent) { create :adherent, id: 42, permit_number: "123456" }