add guardian fields to the medical releases

This commit is contained in:
bilal
2020-06-22 19:02:40 +02:00
committed by Bilal
parent 319cd89b29
commit c3fcbba6fd
10 changed files with 514 additions and 18 deletions

View File

@@ -45,6 +45,9 @@ class Public::MedicalReleasesController < Public::BaseController
.require(:medical_release)
.permit(
person_params,
guardian_params,
second_guardian_params,
:minor,
:signature_base64,
:locale,
:contract_template,
@@ -60,17 +63,49 @@ class Public::MedicalReleasesController < Public::BaseController
end
def person_params
[
:person_first_name,
:person_last_name,
:person_phone,
:person_email,
:person_address_street1,
:person_address_street2,
:person_address_city,
:person_address_state,
:person_address_zip,
:person_address_country,
%i[
person_first_name
person_last_name
person_phone
person_email
person_address_street1
person_address_street2
person_address_city
person_address_state
person_address_zip
person_address_country
]
end
def guardian_params
%i[
guardian_first_name
guardian_last_name
guardian_phone
guardian_email
guardian_photo
guardian_address_street1
guardian_address_street2
guardian_address_city
guardian_address_state
guardian_address_zip
guardian_address_country
]
end
def second_guardian_params
%i[
guardian_2_first_name
guardian_2_last_name
guardian_2_phone
guardian_2_email
guardian_2_photo
guardian_2_address_street1
guardian_2_address_street2
guardian_2_address_city
guardian_2_address_state
guardian_2_address_zip
guardian_2_address_country
]
end

View File

@@ -7,6 +7,10 @@ class MedicalRelease < ApplicationRecord
include Signable
include Syncable
include PersonName
include GuardianPhotoable
include SecondGuardianPhotoable
include GuardianName
include SecondGuardianName
NUMBER_OF_CUSTOM_FIELDS = 15
@@ -31,6 +35,12 @@ class MedicalRelease < ApplicationRecord
acts_as_taggable_on :internal_tags, :tags
# These validations apply to releases being signed by a minor
with_options if: :minor? do
validates :guardian_email, email: true, allow_blank: true
validates :guardian_2_email, email: true, allow_blank: true
end
# These validations apply to releases created natively by the system (i.e. not imported from elsewhere)
with_options on: :native do
validates :signature, attached: true
@@ -63,10 +73,6 @@ class MedicalRelease < ApplicationRecord
false
end
def minor?
false
end
def contract_file_name
"#{project.name.parameterize}_#{contract_template.release_type}_#{(signed_at || created_at).strftime("%Y.%m.%d")}_#{release_number}_#{filename_suffix.parameterize}"
end

View File

@@ -2,7 +2,7 @@
<%= field_set_tag content_tag(:span, t(".release_info.heading"), class: "h6 text-muted text-uppercase") do %>
<div class="form-row">
<%= form.text_field :name, wrapper_class: "col-sm-6" %>
<%= form.select :release_type, options_for_release_type_select(project, @release_type), { wrapper_class: "col-sm-6" }, data: { toggle: "collapse-select", target_show_values_mapping: { "#guardian_clause": %w(appearance talent misc), "#fee_field": %w(appearance talent location material acquired_media), "#exploitable_rights_fields": %w(appearance talent location material acquired_media), "#custom_fields": %w(medical) } }, class: "form-control custom-select" %>
<%= form.select :release_type, options_for_release_type_select(project, @release_type), { wrapper_class: "col-sm-6" }, data: { toggle: "collapse-select", target_show_values_mapping: { "#guardian_clause": %w(appearance talent misc medical), "#fee_field": %w(appearance talent location material acquired_media), "#exploitable_rights_fields": %w(appearance talent location material acquired_media), "#custom_fields": %w(medical) } }, class: "form-control custom-select" %>
</div>
<div class="form-row" id="fee_field">
<%= form.number_field :fee, min:"0", max:"99999999", step: "0.01", prepend: "$", help: "Leave at $0.00 for no-fee", wrapper_class: "col-sm-6" %>

View File

@@ -13,6 +13,17 @@
<% end %>
<hr>
<% unless @contract_template.guardian_clause.blank? %>
<%= form.form_group :minor do %>
<%= form.check_box :minor, label: t("helpers.label.medical_release.minor"), data: { target: "[data-ujs-target=guardian-fields]", toggle: "collapse" } %>
<% end %>
<%= card_field_set_tag t(".guardian_clause.heading") do %>
<p><%= @contract_template.guardian_clause %></p>
<% end %>
<hr>
<% end %>
<% if (1..MedicalRelease::NUMBER_OF_CUSTOM_FIELDS).map {|n| @contract_template.public_send("question_#{n}_text").presence }.compact.any? %>
<%= card_field_set_tag t(".questionnaire.heading") do %>
@@ -44,6 +55,97 @@
<%= render "shared/photos_dropzone_fields", form: form, release: @medical_release %>
<% end %>
<% unless @contract_template.guardian_clause.blank? %>
<div class="<%= class_string("collapse" => !@medical_release.minor?) %>" data-ujs-target="guardian-fields">
<%= card_field_set_tag t(".guardian_info.heading") do %>
<div class="form-row">
<%= form.text_field :guardian_first_name, required: @medical_release.minor?, wrapper_class: "col-sm-3" %>
<%= form.text_field :guardian_last_name, required: @medical_release.minor?, wrapper_class: "col-sm-3" %>
<%= form.phone_field :guardian_phone, required: @medical_release.minor?, wrapper_class: "col-sm-6" %>
</div>
<div class="form-row">
<%= form.text_field :guardian_email, required: @medical_release.minor?, wrapper_class: "col-sm-6" %>
</div>
<%= render "shared/address_fields", form: form, subject: "guardian", required: @medical_release.minor? %>
<% end %>
<hr>
<%= card_field_set_tag t(".guardian_photo.heading") do %>
<div class="alert alert-warning font-weight-bold"><%= t ".guardian_photo.instructions" %></div>
<div class="text-center">
<div class="d-inline-block mb-2" data-behavior="guardian-photo-preview" data-file-input="[data-ujs-target=guardian-photo-input]">
<div class="align-items-center d-flex photo-preview img-thumbnail justify-content-center">
<span><%= t ".photo.no_photo" %></span>
</div>
</div>
<div class="d-inline-block text-left">
<% if @medical_release.guardian_photo.attached? %>
<%= javascript_tag nonce: true do %>
App.PhotoPreview.set("[data-behavior=guardian-photo-preview]", "<%= url_for(@medical_release.guardian_photo.variant(auto_orient: true, resize: '200x200')) %>");
<% end %>
<% end %>
<div class="hidden-file-input">
<%= form.hidden_field :guardian_photo, value: form.object.guardian_photo.signed_id if @medical_release.guardian_photo.attached? %>
<%= form.file_field :guardian_photo, required: @medical_release.minor?, hide_label: true, data: { ujs_target: "guardian-photo-input" }, accept: @medical_release.class.face_photo_acceptable_content_types.join(","), direct_upload: true %>
</div>
<%= button_tag t(".photo.take_photo"), type: "button", class: "btn btn-lg btn-primary take-photo-button", data: { behavior: "take-guardian-photo" } %>
</div>
<p class="p-2 font-weight-bold">
<%= fa_icon "arrow-up", text: t(".photo.camera_instructions_html") %><br>
<small class="text-muted"><%= t ".photo.warning" %></small>
</p>
</div>
<% end %>
<hr>
<%= card_field_set_tag t(".guardian_2_info.heading") do %>
<div class="form-row">
<%= form.text_field :guardian_2_first_name, wrapper_class: "col-sm-3" %>
<%= form.text_field :guardian_2_last_name, wrapper_class: "col-sm-3" %>
<%= form.phone_field :guardian_2_phone, wrapper_class: "col-sm-6" %>
</div>
<div class="form-row">
<%= form.text_field :guardian_2_email, wrapper_class: "col-sm-6" %>
</div>
<%= render "shared/address_fields", form: form, subject: "guardian_2" %>
<% end %>
<hr>
<%= card_field_set_tag t(".guardian_2_photo.heading") do %>
<div class="alert alert-warning font-weight-bold"><%= t ".guardian_2_photo.instructions" %></div>
<div class="text-center">
<div class="d-inline-block mb-2" data-behavior="guardian-photo-preview" data-file-input="[data-ujs-target=guardian-2-photo-input]">
<div class="align-items-center d-flex photo-preview img-thumbnail justify-content-center">
<span><%= t ".photo.no_photo" %></span>
</div>
</div>
<div class="d-inline-block text-left">
<% if @medical_release.guardian_2_photo.attached? %>
<%= javascript_tag nonce: true do %>
App.PhotoPreview.set("[data-behavior=guardian-photo-preview]", "<%= url_for(@medical_release.guardian_2_photo.variant(auto_orient: true, resize: '200x200')) %>");
<% end %>
<% end %>
<div class="hidden-file-input">
<%= form.hidden_field :guardian_2_photo, value: form.object.guardian_2_photo.signed_id if @medical_release.guardian_2_photo.attached? %>
<%= form.file_field :guardian_2_photo, hide_label: true, data: { ujs_target: "guardian-2-photo-input" }, accept: @medical_release.class.face_photo_acceptable_content_types.join(","), direct_upload: true %>
</div>
<%= button_tag t(".photo.take_photo"), type: "button", class: "btn btn-lg btn-primary take-photo-button", data: { behavior: "take-guardian-2-photo" } %>
</div>
<p class="p-2 font-weight-bold">
<%= fa_icon "arrow-up", text: t(".photo.camera_instructions_html") %><br>
<small class="text-muted"><%= t ".photo.warning" %></small>
</p>
</div>
<% end %>
<hr>
</div>
<% end %>
<%= card_field_set_tag t(".signature.heading") do %>
<%= render "shared/signature_fields", form: form %>
<% end %>

View File

@@ -437,6 +437,40 @@ en:
file: Video file
name: Episode name
number: Episode number
medical_release:
person_address_city: City
person_address_country: Country
person_address_state: State
person_address_street1: Address
person_address_street2: Address (Line 2)
person_address_zip: Zip code
person_date_of_birth: Date of birth
person_email: Email address
person_first_name: First name
person_last_name: Last name
person_name: Name
person_phone: Phone number
guardian_2_address_city: Second guardian city
guardian_2_address_country: Second guardian country
guardian_2_address_state: Second guardian state
guardian_2_address_street1: Second guardian address
guardian_2_address_street2: Second guardian address (Line 2)
guardian_2_address_zip: Second guardian zip code
guardian_2_email: Second guardian email
guardian_2_first_name: Second guardian first name
guardian_2_last_name: Second guardian last name
guardian_2_phone: Second guardian phone
guardian_address_city: Guardian city
guardian_address_country: Guardian country
guardian_address_state: Guardian state
guardian_address_street1: Guardian address
guardian_address_street2: Guardian address (Line 2)
guardian_address_zip: Guardian zip code
guardian_first_name: Guardian first name
guardian_last_name: Guardian last name
guardian_email: Guardian email
guardian_phone: Guardian phone
minor: Is the person a minor?
placeholder:
acquired_media_release:
name: Collection Name
@@ -664,7 +698,7 @@ en:
destroy:
alert: The misc release has been deleted
index:
actions:
actions:
search: Search
empty: Misc Releases will appear here
table_headers:
@@ -911,12 +945,16 @@ en:
instructions: Now, enter your personal information.
photo:
heading: Photos
no_photo: No photo yet
take_photo: Take Photo
camera_instructions_html: Click <em>Take Photo</em> to Turn ON Camera
warning: If your photo appears sideways, it will be autocorrected when you submit your release.
questionnaire:
heading: Questionnaire
signature:
heading: Signature
misc_releases:
create:
create:
notice: Your release has been signed. Thank you!
new:
cancel: Cancel
@@ -943,6 +981,20 @@ en:
heading: Photos
signature:
heading: Signature
guardian_clause:
heading: Guardian Clause
guardian_info:
heading: Guardian Information
guardian_photo:
heading: Guardian Photo
instructions: >
Lastly, it's time for guardian to take a selfie photo! Please remove your hat and sunglasses (regular eyewear is ok), make sure that you are the only person in the photo, look straight into the camera, and say Cheese!
guardian_2_info:
heading: Second Guardian Information
guardian_2_photo:
heading: Second Guardian Photo
instructions: >
Lastly, it's time for second guardian to take a selfie photo! Please remove your hat and sunglasses (regular eyewear is ok), make sure that you are the only person in the photo, look straight into the camera, and say Cheese!
talent_releases:
create:
notice: Your release has been signed. Thank you!

View File

@@ -150,6 +150,22 @@ es:
name: Nómbre del proyecto de vídeo
producer_address: Dirección del productor
producer_name: Nómbre del productor
medical_release:
minor: El firmante es un menor
guardian_address_zip: Guardian ZIP (ES)
guardian_address_state: Guardian State (ES)
guardian_address_city: Guardian City (ES)
guardian_address_street1: Guardian address (ES)
guardian_address_street2: Guardian address (line 2) (ES)
guardian_email: Guardian email (ES)
guardian_last_name: Guardian Last name (ES)
guardian_phone: Guardian Phone (ES)
guardian_first_name: Guardian First name (ES)
person_address_zip: Person ZIP (ES)
person_address_state: Person State (ES)
person_address_city: Person City (ES)
person_address_street1: Person Address (ES)
person_address_street2: Person Address (line 2) (ES)
placeholder:
appearance_release:
person_address: Calle, Número de apartamento, Ciudad, Estado, Código Postal
@@ -229,6 +245,27 @@ es:
show:
choose_project: ¿Qué proyecto de la lista de abajo asistirá?
welcome_html: Bienvenidos a la plataforma de firma autorizaciónes de <strong>%{name}</strong>
medical_releases:
new:
guardian_clause:
heading: Guardian Clause (ES)
guardian_info:
heading: Gurdian Information (ES)
guardian_photo:
heading: Guardian Photo (ES)
instructions: >
(ES) Lastly, it's time for guardian to take a selfie photo! Please remove your hat and sunglasses (regular eyewear is ok), make sure that you are the only person in the photo, look straight into the camera, and say Cheese! (ES)
photo:
no_photo: No hay foto todavía
take_photo: Take Photo (ES)
camera_instructions_html: Haga clic en <em>Take Photo</em> para encender la cámara
warning: Si su foto aparece de lado, se corregirá automáticamente cuando actualizar la autorización
guardian_2_info:
heading: Second Guardian Information (ES)
guardian_2_photo:
heading: Second Guardian Photo (ES)
instructions: >
(ES) Lastly, it's time for second guardian to take a selfie photo! Please remove your hat and sunglasses (regular eyewear is ok), make sure that you are the only person in the photo, look straight into the camera, and say Cheese! (ES)
shared:
print: Print (ES)
talent_releases:

View File

@@ -0,0 +1,25 @@
class AddGuardiansFieldsToMedicalReleases < ActiveRecord::Migration[6.0]
def change
add_column :medical_releases, :minor, :boolean, default: false
add_column :medical_releases, :guardian_first_name, :string
add_column :medical_releases, :guardian_last_name, :string
add_column :medical_releases, :guardian_email, :string
add_column :medical_releases, :guardian_phone, :string
add_column :medical_releases, :guardian_address_street1, :string
add_column :medical_releases, :guardian_address_street2, :string
add_column :medical_releases, :guardian_address_city, :string
add_column :medical_releases, :guardian_address_state, :string
add_column :medical_releases, :guardian_address_zip, :string
add_column :medical_releases, :guardian_address_country, :string
add_column :medical_releases, :guardian_2_first_name, :string
add_column :medical_releases, :guardian_2_last_name, :string
add_column :medical_releases, :guardian_2_email, :string
add_column :medical_releases, :guardian_2_phone, :string
add_column :medical_releases, :guardian_2_address_street1, :string
add_column :medical_releases, :guardian_2_address_street2, :string
add_column :medical_releases, :guardian_2_address_city, :string
add_column :medical_releases, :guardian_2_address_state, :string
add_column :medical_releases, :guardian_2_address_zip, :string
add_column :medical_releases, :guardian_2_address_country, :string
end
end

View File

@@ -16,6 +16,7 @@ FactoryBot.define do
appearance_release: true,
location_release: true,
material_release: true,
medical_release: true,
music_release: true,
talent_release: true,
video_analysis: true,

View File

@@ -28,6 +28,18 @@ RSpec.feature 'User manages contract templates', type: :feature do
expect(page).to have_content('The release template has been created')
end
scenario 'medical release template has a guardian clause field' do
visit new_project_contract_template_path(project)
fill_in 'Name', with: 'My Release Template'
select 'Medical Release', from: 'Release type'
fill_hidden guardian_clause_field, with: 'Guardian clause text'
click_on 'Create Release Template'
expect(page).to have_content('The release template has been created')
expect(ContractTemplate.last.guardian_clause.body.to_s).to match /Guardian clause text/
end
scenario 'preview new talent release template without guardian clause' do
visit new_project_contract_template_path(project)
select 'Talent Release', from: 'Release type'

View File

@@ -4,6 +4,125 @@ feature "User managing medical releases" do
let(:current_user) { create(:user) }
let(:project) { create(:project, members: current_user, account: current_user.primary_account) }
context "when signed out" do
scenario 'creating a release for an adult', js: true do
allow(BrayniacAI::Validation).to receive(:create).and_return(double(:validation, valid: true))
project = create(:project, members: current_user, account: current_user.primary_account)
contract_template = create(:contract_template, project: project)
visit new_account_project_contract_template_medical_release_path(project.account, project, contract_template)
fill_in person_first_name_field, with: 'Jane'
fill_in person_last_name_field, with: 'Doe'
fill_in_person_address_fields
fill_in person_phone_field, with: '555-555-5555'
fill_in person_email_field, with: 'jane.doe@test.com'
drop_file Rails.root.join(file_fixture("person_photo.png")), type: :dropzone
draw_signature file_fixture("signature.png"), "medical_release_signature_base64"
expect do
click_button submit_release_button
end.to change(MedicalRelease, :count).by(1)
expect(page).to have_content(successful_submission_message)
end
scenario 'creating a release for a minor', js: true do
allow(BrayniacAI::Validation).to receive(:create).and_return(double(:validation, valid: true))
project = create(:project, members: current_user, account: current_user.primary_account)
contract_template = create(:contract_template, project: project)
visit new_account_project_contract_template_medical_release_path(project.account, project, contract_template)
expect(page).not_to have_content('GUARDIAN INFORMATION')
expect(page).not_to have_content('GUARDIAN PHOTO')
page.check person_is_minor_checkbox
expect(page).to have_content('GUARDIAN INFORMATION')
expect(page).to have_content('GUARDIAN PHOTO')
expect(page).to have_content 'Guardian Email'
fill_in guardian_first_name_field, with: 'Guardian'
fill_in guardian_last_name_field, with: 'Name'
fill_in guardian_phone_field, with: '001101'
fill_in person_first_name_field, with: 'Jane'
fill_in person_last_name_field, with: 'Doe'
fill_in_person_address_fields
fill_in person_phone_field, with: '555-555-5555'
fill_in person_email_field, with: 'jane.doe@test.com'
drop_file Rails.root.join(file_fixture("person_photo.png")), type: :dropzone
attach_file guardian_photo_field, file_fixture('hemsworth.jpeg'), visible: :all
draw_signature file_fixture('signature.png'), 'medical_release_signature_base64'
fill_in guardian_email_field, with: 'invalid@email'
click_button submit_release_button
expect(page).to have_content('Guardian email is not an email')
fill_in guardian_email_field, with: 'valid@email.com'
fill_in_guardian_address_fields
attach_file guardian_photo_field, file_fixture('hemsworth.jpeg'), visible: :all
draw_signature file_fixture('signature.png'), 'medical_release_signature_base64'
click_button submit_release_button
expect(page).to have_content(successful_submission_message)
end
scenario 'creating a release for a minor with two guardians', js: true do
allow(BrayniacAI::Validation).to receive(:create).and_return(double(:validation, valid: true))
project = create(:project, members: current_user, account: current_user.primary_account)
contract_template = create(:contract_template, project: project)
visit new_account_project_contract_template_medical_release_path(project.account, project, contract_template)
expect(page).not_to have_content('SECOND GUARDIAN INFORMATION')
expect(page).not_to have_content('SECOND GUARDIAN PHOTO')
page.check person_is_minor_checkbox
expect(page).to have_content('GUARDIAN INFORMATION')
expect(page).to have_content('GUARDIAN PHOTO')
expect(page).to have_content 'Guardian Email'
expect(page).to have_content 'SECOND GUARDIAN INFORMATION'
expect(page).to have_content 'SECOND GUARDIAN PHOTO'
expect(page).to have_content 'Second Guardian Email'
expect(page).to have_content 'Second Guardian Phone'
expect(page).to have_content 'Second Guardian Address'
fill_in guardian_first_name_field, with: 'Guardian'
fill_in guardian_last_name_field, with: 'Name'
fill_in guardian_phone_field, with: '001101'
fill_in person_first_name_field, with: 'Jane'
fill_in person_last_name_field, with: 'Doe'
fill_in_person_address_fields
fill_in person_phone_field, with: '555-555-5555'
fill_in person_email_field, with: 'jane.doe@test.com'
drop_file Rails.root.join(file_fixture("person_photo.png")), type: :dropzone
attach_file guardian_photo_field, file_fixture('hemsworth.jpeg'), visible: :all
draw_signature file_fixture('signature.png'), 'medical_release_signature_base64'
fill_in guardian_email_field, with: 'invalid@email'
click_button submit_release_button
expect(page).to have_content('Guardian email is not an email')
fill_in guardian_email_field, with: 'valid@email.com'
fill_in_guardian_address_fields
attach_file guardian_photo_field, file_fixture('hemsworth.jpeg'), visible: :all
draw_signature file_fixture('signature.png'), 'medical_release_signature_base64'
fill_in guardian_2_first_name_field, with: 'Second'
fill_in guardian_2_last_name_field, with: 'Guardian'
fill_in guardian_2_phone_field, with: '999'
click_button submit_release_button
expect(page).to have_content(successful_submission_message)
expect(MedicalRelease.last.guardian_2_first_name).to eq 'Second'
end
end
context "when signed in as account manager" do
before do
sign_in current_user
@@ -142,4 +261,111 @@ feature "User managing medical releases" do
def view_release_pdf_link_for(release)
['Download', href: medical_release_contracts_path(release, format: 'pdf')]
end
def person_first_name_field
"medical_release[person_first_name]"
end
def person_last_name_field
"medical_release[person_last_name]"
end
def person_email_field
"medical_release[person_email]"
end
def person_phone_field
"medical_release[person_phone]"
end
def submit_release_button
t 'shared.submit_release_short'
end
def successful_submission_message
"Your release was successfully submitted. Thank you."
end
def fill_in_person_address_fields
fill_in person_address_street1_field, with: "123 Test Lane"
fill_in person_address_city_field, with: "New York"
fill_in person_address_state_field, with: "NY"
fill_in person_address_zip_field, with: '1000'
end
def fill_in_guardian_address_fields
fill_in guardian_address_street1_field, with: "124 Test Lane"
fill_in guardian_address_city_field, with: "New York"
fill_in guardian_address_state_field, with: "NY"
fill_in guardian_address_zip_field, with: '1000'
end
def person_address_street1_field
t('helpers.label.medical_release.person_address_street1')
end
def person_address_city_field
t('helpers.label.medical_release.person_address_city')
end
def person_address_state_field
t('helpers.label.medical_release.person_address_state')
end
def person_address_zip_field
t('helpers.label.medical_release.person_address_zip')
end
def guardian_first_name_field
t('helpers.label.medical_release.guardian_first_name')
end
def guardian_last_name_field
t('helpers.label.medical_release.guardian_last_name')
end
def guardian_phone_field
t('helpers.label.medical_release.guardian_phone')
end
def guardian_email_field
t('helpers.label.medical_release.guardian_email')
end
def guardian_address_street1_field
t('helpers.label.medical_release.guardian_address_street1')
end
def guardian_address_city_field
t('helpers.label.medical_release.guardian_address_city')
end
def guardian_address_state_field
t('helpers.label.medical_release.guardian_address_state')
end
def guardian_address_zip_field
t('helpers.label.medical_release.guardian_address_zip')
end
def guardian_photo_field
'medical_release[guardian_photo]'
end
def person_is_minor_checkbox
'medical_release_minor'
end
def guardian_2_first_name_field
'Second guardian first name'
end
def guardian_2_last_name_field
'Second guardian last name'
end
def guardian_2_phone_field
'Second guardian phone'
end
end