diff --git a/app/controllers/contract_templates_controller.rb b/app/controllers/contract_templates_controller.rb index 10ed045..eabc95a 100644 --- a/app/controllers/contract_templates_controller.rb +++ b/app/controllers/contract_templates_controller.rb @@ -82,7 +82,7 @@ class ContractTemplatesController < ApplicationController params .require(:contract_template) .permit(:name, :release_type, :body, :guardian_clause, - :signature_legal_text, :fee, + :signature_legal_text, :fee, :amendment_clause, :applicable_medium_id, :applicable_medium_text, :territory_id, :territory_text, :term_id, :term_text, :accessibility, diff --git a/app/controllers/public/amendments_controller.rb b/app/controllers/public/amendments_controller.rb new file mode 100644 index 0000000..4182aa7 --- /dev/null +++ b/app/controllers/public/amendments_controller.rb @@ -0,0 +1,47 @@ +class Public::AmendmentsController < Public::BaseController + skip_after_action :verify_authorized, :verify_policy_scoped + before_action :set_account, :set_project, :set_contract_template, :set_release + + def new + if @release.amendment_signed? + render :create, locals: { already_signed: true } + end + end + + def create + if @release.amendment_signed? + render :create, locals: { already_signed: true } + return + end + + @release.attributes = amendment_params + + render :new unless @release.save(context: :amendment) + end + + private + + def amendment_params + params.require(releasable_param.name).permit(:amendment_signer_name, :amendment_signature_base64) + end + + def releasable_param + @releasable_param ||= ReleasableParam.new(params.to_unsafe_h) + end + + def set_release + @release = @contract_template.releases.find(releasable_param.id) + end + + def set_contract_template + @contract_template = @project.contract_templates.find(params[:contract_template_id]) + end + + def set_project + @project = @account.projects.find(params[:project_id]) + end + + def set_account + @account = Account.find_by(slug: params[:account_id]) + end +end \ No newline at end of file diff --git a/app/models/concerns/amendmenable.rb b/app/models/concerns/amendmenable.rb new file mode 100644 index 0000000..3004c7d --- /dev/null +++ b/app/models/concerns/amendmenable.rb @@ -0,0 +1,32 @@ +module Amendmenable + extend ActiveSupport::Concern + + included do + include ActiveStorageSupport::SupportForBase64 + + has_one_base64_attached :amendment_signature + + with_options on: :amendment do + validates :amendment_signer_name, presence: true + validates :amendment_signature, attached: true + end + end + + def amendment_signable? + contract_template.present? && contract_template.amendment_clause.present? + end + + def amendment_signed? + amendment_signature.attached? + end + + def amendment_signature_base64 + nil + end + + def amendment_signature_base64=(data_uri) + return if data_uri.blank? + + amendment_signature.attach(data: data_uri, filename: "amendment_signature.png", content_type: "image/png", identify: "false") + end +end diff --git a/app/models/contract_template.rb b/app/models/contract_template.rb index e05ed72..a607b88 100644 --- a/app/models/contract_template.rb +++ b/app/models/contract_template.rb @@ -22,6 +22,7 @@ class ContractTemplate < ApplicationRecord has_rich_text :body has_rich_text :guardian_clause has_rich_text :signature_legal_text + has_rich_text :amendment_clause validates :name, presence: true validates :release_type, presence: true diff --git a/app/models/location_release.rb b/app/models/location_release.rb index f6063e8..266ea07 100644 --- a/app/models/location_release.rb +++ b/app/models/location_release.rb @@ -12,6 +12,7 @@ class LocationRelease < ApplicationRecord include PersonName include CsvExportable include Approvable + include Amendmenable class << self def custom_csv_exportable_headers diff --git a/app/policies/location_release_policy.rb b/app/policies/location_release_policy.rb index ead9d02..16522dd 100644 --- a/app/policies/location_release_policy.rb +++ b/app/policies/location_release_policy.rb @@ -39,6 +39,10 @@ class LocationReleasePolicy < ReleasePolicy user.account_manager? end + def sign_amendment? + user.manager? || user.account_manager? + end + def approve? review? end diff --git a/app/views/contract_templates/_form.html.erb b/app/views/contract_templates/_form.html.erb index 09a0203..15d37ff 100644 --- a/app/views/contract_templates/_form.html.erb +++ b/app/views/contract_templates/_form.html.erb @@ -2,7 +2,7 @@ <%= field_set_tag content_tag(:span, t(".release_info.heading"), class: "h6 text-muted text-uppercase") do %>
<%= 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 medical), "#fee_field": %w(appearance talent location material acquired_media), "#exploitable_rights_fields": %w(appearance talent location material acquired_media), "#custom_fields": %w(medical misc) } }, 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 misc), "#amendment_clause": %w(location) } }, class: "form-control custom-select" %>
<%= form.radio_button :accessibility, :public_template, label: "Public", wrapper_class: "mr-3" %> @@ -29,6 +29,11 @@ <%= form.rich_text_area :guardian_clause %> <% end %>
+
+ <%= form.form_group do %> + <%= form.rich_text_area :amendment_clause %> + <% end %> +
+<% if releasable.respond_to?(:amendment_signed?) && releasable.amendment_signed? %> +
+ <%= render "contracts/amendment_page", releasable: releasable, preview: preview %> +
+<%end %> + <% if releasable.respond_to?(:approved?) && releasable.approved? %>
<%= render "contracts/for_office_use_only", releasable: releasable, preview: preview %> diff --git a/app/views/location_releases/_location_release.html.erb b/app/views/location_releases/_location_release.html.erb index e5b9c76..a829689 100644 --- a/app/views/location_releases/_location_release.html.erb +++ b/app/views/location_releases/_location_release.html.erb @@ -30,6 +30,17 @@ <%= location_release.signed_on %> + + <% if location_release.amendment_signed? %> + + <% elsif location_release.amendment_signable? %> + + <% end %> +
@@ -44,6 +55,9 @@ <% if policy(location_release).edit_photos? %> <%= link_to fa_icon("picture-o fw", text: "Photos"), [:edit, location_release, :photos], class: "dropdown-item" %> <% end %> + <% if policy(location_release).sign_amendment? && location_release.amendment_signable? && !location_release.amendment_signed? %> + <%= link_to fa_icon("file-text fw", text: t('.actions.sign_amendment')), [:new, location_release.project.account, location_release.project, location_release.contract_template, location_release, :amendment], class: "dropdown-item", target: "_blank" %> + <% end %> <% if policy(Contract).show? && (location_release.contract.attached? || location_release.contract_template.present?) %> <%= link_to fa_icon("download fw", text: "Download"), [location_release, :contracts, format: "pdf"], class: "dropdown-item", target: "_blank" %> <% end %> diff --git a/app/views/location_releases/index.html.erb b/app/views/location_releases/index.html.erb index 96ec918..f2aced3 100644 --- a/app/views/location_releases/index.html.erb +++ b/app/views/location_releases/index.html.erb @@ -32,8 +32,8 @@ <%= t(".table_headers.address") %> <%= t(".table_headers.notes") %> <%= t(".table_headers.tags") %> - <%= t(".table_headers.signed_at") %> - + <%= t(".table_headers.signed_at") %> + diff --git a/app/views/public/amendments/create.html.erb b/app/views/public/amendments/create.html.erb new file mode 100644 index 0000000..cdc2055 --- /dev/null +++ b/app/views/public/amendments/create.html.erb @@ -0,0 +1,3 @@ +<% message = local_assigns[:already_signed] ? t('.amendment_already_signed_message') : t('.amendment_signed_message') %> +<% alert_type = local_assigns[:already_signed] ? "alert-warning" : "alert-success" %> +

<%= message %>

diff --git a/app/views/public/amendments/new.html.erb b/app/views/public/amendments/new.html.erb new file mode 100644 index 0000000..24b31c3 --- /dev/null +++ b/app/views/public/amendments/new.html.erb @@ -0,0 +1,30 @@ + + + +
+
+ <%= errors_summary_for @release %> + <%= bootstrap_form_with model: @release, method: :post, url: public_send("account_project_contract_template_#{@contract_template.release_type}_release_amendments_path"), local: true do |form| %> + <%= card_field_set_tag t(".amendment.heading") do %> +

<%= @contract_template.amendment_clause %>

+ <% end %> + +
+ +
+ <%= form.text_field :amendment_signer_name, required: true, wrapper_class: "col-sm-6" %> +
+ + <%= card_field_set_tag t(".signature.heading") do %> + <%= render "shared/signature_fields", signature_field: :amendment_signature_base64, form: form %> + <% end %> + +
+ <%= form.button t("shared.submit_release_long"), class: "btn btn-block btn-lg btn-success", data: { disable_with: t("shared.disable_with") } %> +
+ <% end %> +
+
diff --git a/app/views/shared/_signature_fields.html.erb b/app/views/shared/_signature_fields.html.erb index eb1fc6e..ec2b3dc 100644 --- a/app/views/shared/_signature_fields.html.erb +++ b/app/views/shared/_signature_fields.html.erb @@ -1,3 +1,4 @@ +<% signature_field = local_assigns[:signature_field] ? local_assigns[:signature_field] : :signature_base64 %> <% if local_assigns[:instruction] %> @@ -6,7 +7,7 @@ <% end %> -<%= form.hidden_field :signature_base64, data: { ujs_target: "signature-input" } %> +<%= form.hidden_field signature_field, data: { ujs_target: "signature-input" } %>
<%= button_tag class: "btn btn-sm btn-danger", data: { behavior: "clear-digital-signature" } do %> <%= fa_icon "refresh" %> <%= t "shared.clear" %> diff --git a/config/locales/en.yml b/config/locales/en.yml index 0031f0f..12d6f36 100644 --- a/config/locales/en.yml +++ b/config/locales/en.yml @@ -323,6 +323,12 @@ en: update: notice: The release template has been updated contracts: + amendment_page: + description_labels: + amendment_clause: Amendment Clause + amendment_signature: Amendment Signature + amendment_signer_name: Amendment Signer Name + heading: Amendment for_office_use_only: description_labels: date_issued: Date Issued @@ -405,6 +411,7 @@ en: helpers: help: contract_template: + amendment_clause: Leave blank if not required for this contract fee: Leave at $0.00 for no-fee guardian_clause: Leave blank if not required for this contract signature_legal_text: Leave blank if not required for this contract @@ -780,7 +787,10 @@ en: actions: manage: Manage review: Review + sign_amendment: Sign Amendment messages: + amendment_not_signed_tooltip: Amendment not yet signed + amendment_signed_tooltip: Amendment Signed approved_tooltip: Approved by %{user} on %{timestamp} no_photos: Needs Photo new: @@ -1027,6 +1037,16 @@ en: heading: Licensor/Owner Contact Information signature: heading: Signature + amendments: + create: + amendment_already_signed_message: Release amendment is already signed! + amendment_signed_message: Release amendment signed successfully! Thank you + new: + amendment: + heading: Amendment + copy_url: Copy sign amendment URL + signature: + heading: Signature appearance_releases: create: notice: Your release has been signed. Thank you! diff --git a/config/locales/es.yml b/config/locales/es.yml index 00d454a..9d2f19b 100644 --- a/config/locales/es.yml +++ b/config/locales/es.yml @@ -148,6 +148,12 @@ es: update: notice: The release template has been updated (ES) contracts: + amendment_page: + description_labels: + amendment_clause: Amendment Clause (ES) + amendment_signature: Amendment Signature (ES) + amendment_signer_name: Amendment Signer Name (ES) + heading: Amendment (ES) for_office_use_only: description_labels: date_issued: Date Issued (ES) @@ -207,6 +213,7 @@ es: helpers: help: contract_template: + amendment_clause: Leave blank if not required for this contract (ES) fee: Leave at $0.00 for no-fee (ES) guardian_clause: Leave blank if not required for this contract (ES) signature_legal_text: Leave blank if not required for this contract (ES) @@ -338,6 +345,12 @@ es: notes: Notes (ES) signed_at: Date Signed (ES) tags: Tags (ES) + location_release: + actions: + sign_amendment: Sign Amendment (ES) + messages: + amendment_not_signed_tooltip: Amendment not yet signed (ES) + amendment_signed_tooltip: Amendment Signed (ES) material_releases: form: photos: @@ -384,6 +397,16 @@ es: signed_at: Date Signed (ES) tags: Tags (ES) public: + amendments: + create: + amendment_already_signed_message: Release amendment is already signed! (ES) + amendment_signed_message: Release amendment signed successfully! Thank you (ES) + new: + amendment: + heading: Amendment + copy_url: Copy sign amendment URL (ES) + signature: + heading: Signature (ES) appearance_releases: create: notice: La autorización está firmada. ¡Gracias! diff --git a/config/routes.rb b/config/routes.rb index 6f2e9a9..0bf991e 100644 --- a/config/routes.rb +++ b/config/routes.rb @@ -128,7 +128,9 @@ Rails.application.routes.draw do resources :talent_releases, only: [:new, :create] resources :appearance_releases, only: [:new, :create] resources :acquired_media_releases, only: [:new, :create] - resources :location_releases, only: [:new, :create] + resources :location_releases, only: [:new, :create] do + resources :amendments, only: [:new, :create] + end resources :material_releases, only: [:new, :create] resources :medical_releases, only: [:new, :create] resources :misc_releases, only: [:new, :create] diff --git a/db/migrate/20200721140821_add_amendment_signer_details_to_location_releases.rb b/db/migrate/20200721140821_add_amendment_signer_details_to_location_releases.rb new file mode 100644 index 0000000..3c1e448 --- /dev/null +++ b/db/migrate/20200721140821_add_amendment_signer_details_to_location_releases.rb @@ -0,0 +1,5 @@ +class AddAmendmentSignerDetailsToLocationReleases < ActiveRecord::Migration[6.0] + def change + add_column :location_releases, :amendment_signer_name, :string + end +end diff --git a/db/structure.sql b/db/structure.sql index a10feff..76a20f1 100644 --- a/db/structure.sql +++ b/db/structure.sql @@ -888,7 +888,8 @@ CREATE TABLE public.location_releases ( filming_hours text, approved_by_user_name text, approved_by_user_email text, - approved_at timestamp without time zone + approved_at timestamp without time zone, + amendment_signer_name character varying ); @@ -3942,6 +3943,7 @@ INSERT INTO "schema_migrations" (version) VALUES ('20200716103525'), ('20200716105723'), ('20200720051634'), -('20200720131309'); +('20200720131309'), +('20200721140821'); diff --git a/spec/controllers/public/amendments_controller_spec.rb b/spec/controllers/public/amendments_controller_spec.rb new file mode 100644 index 0000000..277212e --- /dev/null +++ b/spec/controllers/public/amendments_controller_spec.rb @@ -0,0 +1,112 @@ +require 'rails_helper' + +RSpec.describe Public::AmendmentsController, type: :controller do + let(:user) { create(:user) } + let(:account) { user.primary_account } + let(:project) { create(:project, account: account) } + let(:contract_template) { create(:location_release_contract_template, :with_amendment_clause, project: project) } + let(:location_release) { create(:location_release, contract_template: contract_template, project: project) } + + render_views + + describe "#new" do + it "shows amendment signing form for non-signed amendment of a release" do + expect(location_release.amendment_signed?).to be_falsey + + get :new, params: { + account_id: account, + project_id: project, + contract_template_id: location_release.contract_template, + location_release_id: location_release + } + + expect(response).to be_successful + + body = CGI.unescape_html(response.body) + expect(body).not_to match already_signed_message + end + + it "shows already signed message for signed amendment of a release" do + signed_release = create(:location_release, :amendment_signed, contract_template: contract_template, project: project) + + expect(signed_release.amendment_signed?).to be_truthy + + get :new, params: { + account_id: account, + project_id: project, + contract_template_id: location_release.contract_template, + location_release_id: signed_release + } + + expect(response).to be_successful + + body = CGI.unescape_html(response.body) + expect(body).to match already_signed_message + end + end + + describe "#create" do + it "signs amendment" do + expect(location_release.amendment_signed?).to be_falsey + + post :create, params: { + account_id: account, + project_id: project, + contract_template_id: location_release.contract_template, + location_release_id: location_release, + location_release: { + amendment_signer_name: "Signer Name", + amendment_signature_base64: signature_base64 + } + } + + expect(response).to be_successful + + body = CGI.unescape_html(response.body) + expect(body).not_to match already_signed_message + expect(body).to match signed_successfully_message + + expect(LocationRelease.last.amendment_signed?).to be_truthy + expect(LocationRelease.last.amendment_signer_name).to eq "Signer Name" + end + + it "shows already signed message for signed amendment of a release" do + signed_release = create(:location_release, :amendment_signed, name: "Test Loc", amendment_signer_name: "Big Signer", contract_template: contract_template, project: project) + + expect(signed_release.amendment_signed?).to be_truthy + + post :create, params: { + account_id: account, + project_id: project, + contract_template_id: location_release.contract_template, + location_release_id: signed_release, + location_release: { + amendment_signer_name: "Signer Who", + amendment_signature_base64: signature_base64 + } + } + + expect(response).to be_successful + + body = CGI.unescape_html(response.body) + expect(body).to match already_signed_message + + expect(signed_release.amendment_signed?).to be_truthy + expect(signed_release.amendment_signer_name).to eq "Big Signer" + end + end + + private + + def already_signed_message + t 'public.amendments.create.amendment_already_signed_message' + end + + def signed_successfully_message + t 'public.amendments.create.amendment_signed_message' + end + + def signature_base64 + @signature_base64 ||= Base64Image.from_image(file_fixture('signature.png')).data_uri + end +end diff --git a/spec/factories/contract_templates.rb b/spec/factories/contract_templates.rb index 22583c4..8935cd5 100644 --- a/spec/factories/contract_templates.rb +++ b/spec/factories/contract_templates.rb @@ -13,6 +13,10 @@ FactoryBot.define do archived_at Time.zone.now end + trait :with_amendment_clause do + amendment_clause "Amendment Legal Language" + end + factory :appearance_release_contract_template do release_type "appearance" end diff --git a/spec/factories/location_releases.rb b/spec/factories/location_releases.rb index 727ea50..8ceb6ae 100644 --- a/spec/factories/location_releases.rb +++ b/spec/factories/location_releases.rb @@ -22,6 +22,14 @@ FactoryBot.define do end end + trait :amendment_signed do + amendment_signature do + path = Rails.root.join("spec", "fixtures", "files", "signature.png") + Rack::Test::UploadedFile.new(path, "image/png") + end + amendment_signer_name "Amendment Signer" + end + trait :non_native do contract do path = Rails.root.join("spec", "fixtures", "files", "contract.pdf") diff --git a/spec/features/user_manages_contract_templates_spec.rb b/spec/features/user_manages_contract_templates_spec.rb index 6985b3c..b4add44 100644 --- a/spec/features/user_manages_contract_templates_spec.rb +++ b/spec/features/user_manages_contract_templates_spec.rb @@ -30,7 +30,7 @@ RSpec.feature 'User manages contract templates', type: :feature do fill_in 'Describe other territory', with: 'North America only' select 'In perpetuity', from: 'Term' select 'None', from: 'Restriction' - click_on 'Create Release Template' + click_on create_release_template_button expect(page).to have_content(create_contract_template_success_message) end @@ -48,18 +48,30 @@ RSpec.feature 'User manages contract templates', type: :feature do fill_in_trix signature_legal_text_field, with: 'LL' expect do - click_on 'Create Release Template' + click_on create_release_template_button end.to change(ContractTemplate, :count).by(1) end end + scenario 'location release template has a amendment clause field' do + visit new_project_contract_template_path(project) + + fill_in 'Name', with: 'My Release Template' + select 'Location Release', from: 'Release type' + fill_hidden amendment_clause_field, with: 'Amendment clause text' + click_on create_release_template_button + + expect(page).to have_content(create_contract_template_success_message) + expect(ContractTemplate.last.amendment_clause.body.to_s).to match /Amendment clause text/ + 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' + click_on create_release_template_button expect(page).to have_content(create_contract_template_success_message) expect(ContractTemplate.last.guardian_clause.body.to_s).to match /Guardian clause text/ @@ -78,7 +90,7 @@ RSpec.feature 'User manages contract templates', type: :feature do fill_in_trix 'contract_template_guardian_clause', with: 'Guardian clause text' fill_in question_field(1), with: 'How much experience do you have in the industry?' - click_on 'Create Release Template' + click_on create_release_template_button expect(page).to have_content(create_contract_template_success_message) end @@ -185,13 +197,13 @@ RSpec.feature 'User manages contract templates', type: :feature do scenario 'Should not allow negative fees' do fill_in 'Fee', with: '-200' - click_on 'Create Release Template' + click_on create_release_template_button expect(page).not_to have_content(create_contract_template_success_message) end scenario 'Should not allow fees with more than 9 digits' do fill_in 'Fee', with: '9999999999' - click_on 'Create Release Template' + click_on create_release_template_button expect(page).not_to have_content(create_contract_template_success_message) end end @@ -465,6 +477,10 @@ RSpec.feature 'User manages contract templates', type: :feature do 'contract_template_guardian_clause_trix_input_contract_template' end + def amendment_clause_field + 'contract_template_amendment_clause_trix_input_contract_template' + end + def signature_legal_text_field 'contract_template_signature_legal_text' end @@ -516,4 +532,8 @@ RSpec.feature 'User manages contract templates', type: :feature do def duplicate_release_name(template_name = '') t 'contract_templates.duplicate.name_prefix', template_name: template_name end + + def create_release_template_button + 'Create Release Template' + end end diff --git a/spec/features/user_managing_location_releases_spec.rb b/spec/features/user_managing_location_releases_spec.rb index 4f67d88..db3e53a 100644 --- a/spec/features/user_managing_location_releases_spec.rb +++ b/spec/features/user_managing_location_releases_spec.rb @@ -78,6 +78,47 @@ feature "User managing location releases" do expect(page).to have_content dummy_signature_legal_text end + + scenario "signing amendment for a not-signed amendment release", js: true do + contract_template = create(:location_release_contract_template, :with_amendment_clause, project: project) + release = create(:location_release, contract_template: contract_template, project: project) + + expect(release.amendment_signed?).to be_falsey + + visit new_account_project_contract_template_location_release_amendment_path(project.account, project, contract_template, release) + + expect(page).to have_content amendments_heading + + fill_in amendment_signer_name_field, with: 'Big Signer' + draw_signature file_fixture("signature.png"), amendment_signature_field + + click_button sign_amendment_button + + expect(page).to have_content signed_successfully_message + expect(LocationRelease.find(release.id).amendment_signed?).to be_truthy + end + + scenario "opening signing amendment page for a signed amendment release shows already signed message", js: true do + contract_template = create(:location_release_contract_template, :with_amendment_clause, project: project) + release = create(:location_release, :amendment_signed, contract_template: contract_template, project: project) + + expect(release.amendment_signed?).to be_truthy + + visit new_account_project_contract_template_location_release_amendment_path(project.account, project, contract_template, release) + + expect(page).not_to have_content amendments_heading + expect(page).not_to have_content signed_successfully_message + expect(page).to have_content already_signed_message + end + + scenario "amendment signing form has copy URL button" do + contract_template = create(:location_release_contract_template, :with_amendment_clause, project: project) + release = create(:location_release, contract_template: contract_template, project: project) + + visit new_account_project_contract_template_location_release_amendment_path(project.account, project, contract_template, release) + + expect(page).to have_content copy_url_button + end end context "when signed in" do @@ -108,9 +149,9 @@ feature "User managing location releases" do fill_in filming_hours_field, with: "04:00 - 22:00" click_button create_release_button expect(page).to have_content(create_release_notice) - expect(page).to have_photo("location_photo.png") + expect(page).to have_photo("location_photo.png", visible: :all) - click_on "Manage" + click_on manage_button expect(page).to have_link("Download") end end @@ -119,7 +160,7 @@ feature "User managing location releases" do location_release = create(:location_release_with_photo, :non_native, project: project) visit project_location_releases_path(project) - click_on "Manage" + click_on manage_button click_link *update_location_release_link(location_release) within ".dropzone" do @@ -139,7 +180,7 @@ feature "User managing location releases" do location_release = create(:location_release, project: project) visit project_location_releases_path(project) - click_on "Manage" + click_on manage_button accept_alert do click_link *destroy_location_release_link(location_release) @@ -172,7 +213,7 @@ feature "User managing location releases" do expect(page).to have_content("Needs Photo") - click_on "Manage" + click_on manage_button click_on "Photos" expect(page).to have_content("Add Photos") @@ -182,11 +223,85 @@ feature "User managing location releases" do click_on "Save Changes" expect(page).to have_content("The release has been updated") - expect(page).to have_photo("location_photo.png") + expect(page).to have_photo("location_photo.png", visible: :all) + end + + scenario "signing amendment for a not-signed amendment release", js: true do + contract_template = create(:location_release_contract_template, :with_amendment_clause, project: project) + release = create(:location_release, name: "Test Loc", contract_template: contract_template, project: project) + + expect(release.amendment_signed?).to be_falsey + + visit project_location_releases_path(project) + + expect(page).to have_content "Test Loc" + + click_on manage_button + + expect(page).to have_link sign_amendment_link + + new_window = window_opened_by { click_link sign_amendment_link } + within_window new_window do + expect(page).to have_content amendments_heading + + fill_in amendment_signer_name_field, with: 'Big Signer' + draw_signature file_fixture("signature.png"), amendment_signature_field + + click_button sign_amendment_button + + expect(page).to have_content signed_successfully_message + expect(LocationRelease.find(release.id).amendment_signed?).to be_truthy + end + end + + scenario "signed amendment release does not have sign amendment option in manage dropdown", js: true do + contract_template = create(:location_release_contract_template, :with_amendment_clause, project: project) + release = create(:location_release, :amendment_signed, name: "Test Loc", contract_template: contract_template, project: project) + + expect(release.amendment_signed?).to be_truthy + + visit project_location_releases_path(project) + + expect(page).to have_content "Test Loc" + + click_on manage_button + + expect(page).not_to have_link sign_amendment_link + end + + scenario "signed amendment release have checked box in location releases index table", js: true do + contract_template = create(:location_release_contract_template, :with_amendment_clause, project: project) + not_signed_release = create(:location_release, name: "Not Yet Loc", contract_template: contract_template, project: project) + expect(not_signed_release.amendment_signed?).to be_falsey + + visit project_location_releases_path(project) + + expect(page).to have_content "Not Yet Loc" + expect(page).to have_css('i.fa.fa-square-o', count: 1) + expect(page).to have_css('i.fa.fa-check-square', count: 0) + + signed_release = create(:location_release, :amendment_signed, name: "Signed A Loc", contract_template: contract_template, project: project) + expect(signed_release.amendment_signed?).to be_truthy + + visit project_location_releases_path(project) + + expect(page).to have_content "Signed A Loc" + + expect(page).to have_css('i.fa.fa-square-o', count: 1) + expect(page).to have_css('i.fa.fa-check-square-o', count: 1) + end + + scenario "amendment signing form has copy URL button when user is signed in", js: true do + contract_template = create(:location_release_contract_template, :with_amendment_clause, project: project) + release = create(:location_release, contract_template: contract_template, project: project) + + visit new_account_project_contract_template_location_release_amendment_path(project.account, project, contract_template, release) + + expect(page).to have_content copy_url_button end end - scenario "viewing the contract PDF" do + scenario "viewing the contract PDF when amendment is not yet signed" do location_release = create(:location_release_with_contract_template_and_photo, :native, project: project, @@ -198,16 +313,13 @@ feature "User managing location releases" do content: "Note 1", user: build(:user, email: "jane.doe@test.com"), email: "jane.doe@test.com", - created_at: DateTime.new(2020, 2, 21, 12, 0, 0), - ), + created_at: DateTime.new(2020, 2, 21, 12, 0, 0),), build(:note, content: "Note 2", user: build(:user, email: "john.doe@test.com"), email: "john.doe@test.com", - created_at: DateTime.new(2020, 2, 20, 11, 0, 0), - ), - ] - ) + created_at: DateTime.new(2020, 2, 20, 11, 0, 0),), + ]) sign_in(current_user) visit project_location_releases_path(project) @@ -216,6 +328,8 @@ feature "User managing location releases" do expect(content_type).to eq("application/pdf") expect(content_disposition).to include("inline") expect(pdf_filename).to include("benny-s-burritos") + + expect(pdf_body).not_to have_content amendment_page_heading expect(pdf_body).to have_content("Benny's Burritos") expect(pdf_body).to have_content("NOTES") expect(pdf_body).to have_content("Note 1") @@ -232,6 +346,34 @@ feature "User managing location releases" do expect(pdf_body).to have_content("06:00 - 20:00") end + scenario "viewing the contract PDF when amendment is signed" do + contract_template = create(:location_release_contract_template, :with_amendment_clause, project: project) + location_release = create(:location_release, + :amendment_signed, + :native, + contract_template: contract_template, + project: project, + name: "Test Loc") + + sign_in(current_user) + visit project_location_releases_path(project) + click_link *view_release_pdf_link_for(location_release) + + expect(content_type).to eq("application/pdf") + expect(content_disposition).to include("inline") + expect(pdf_filename).to include("test-loc") + + expect(pdf_body).to have_content("Test Loc") + + expect(pdf_body).to have_content amendment_page_heading + expect(pdf_body).to have_content amendment_clause_label + expect(pdf_body).to have_content amendment_signer_name_label + expect(pdf_body).to have_content amendment_signature_label + + expect(pdf_body).to have_content contract_template.amendment_clause.to_plain_text + expect(pdf_body).to have_content location_release.amendment_signer_name + end + context "when the user is account manager" do let(:current_user) { create(:user, :account_manager) } @@ -327,7 +469,7 @@ feature "User managing location releases" do create(:location_release_with_contract_template, :native, project: project) visit project_location_releases_path(project) - click_on "Manage" + click_on manage_button expect(page).not_to have_link(review_action, exact: true) end @@ -345,7 +487,7 @@ feature "User managing location releases" do visit project_location_releases_path(project) - click_on "Manage" + click_on manage_button expect(page).not_to have_link("Download", exact: true) end @@ -353,7 +495,7 @@ feature "User managing location releases" do create(:location_release_with_contract_template, :native, project: project) visit project_location_releases_path(project) - click_on "Manage" + click_on manage_button expect(page).not_to have_link(review_action, exact: true) end @@ -437,8 +579,8 @@ feature "User managing location releases" do "location_release[filming_hours]" end - def have_photo(filename, attr: "src") - have_selector("img[#{attr}*='#{filename}']") + def have_photo(filename, attr: "src", visible: true) + have_selector("img[#{attr}*='#{filename}']", visible: visible) end def import_location_release_link(project) @@ -535,4 +677,56 @@ feature "User managing location releases" do def date_issued t 'contracts.for_office_use_only.description_labels.date_issued' end + + def amendments_heading + t 'public.amendments.new.amendment.heading' + end + + def amendment_signer_name_field + 'location_release[amendment_signer_name]' + end + + def amendment_signature_field + 'location_release_amendment_signature_base64' + end + + def sign_amendment_button + t 'shared.submit_release_long' + end + + def already_signed_message + t 'public.amendments.create.amendment_already_signed_message' + end + + def signed_successfully_message + t 'public.amendments.create.amendment_signed_message' + end + + def manage_button + t 'location_releases.location_release.actions.manage' + end + + def sign_amendment_link + t 'location_releases.location_release.actions.sign_amendment' + end + + def copy_url_button + t 'public.amendments.new.copy_url' + end + + def amendment_page_heading + t 'contracts.amendment_page.heading' + end + + def amendment_signer_name_label + t 'contracts.amendment_page.description_labels.amendment_signer_name' + end + + def amendment_clause_label + t 'contracts.amendment_page.description_labels.amendment_clause' + end + + def amendment_signature_label + t 'contracts.amendment_page.description_labels.amendment_signature' + end end