diff --git a/app/assets/javascripts/channels/broadcasts.coffee b/app/assets/javascripts/channels/broadcasts.coffee.erb similarity index 93% rename from app/assets/javascripts/channels/broadcasts.coffee rename to app/assets/javascripts/channels/broadcasts.coffee.erb index 823da04..b2e1f4a 100644 --- a/app/assets/javascripts/channels/broadcasts.coffee +++ b/app/assets/javascripts/channels/broadcasts.coffee.erb @@ -21,10 +21,11 @@ $(document).on "turbolinks:load", -> refreshBroadcastVideo: (data) -> $("#broadcast_updates").html data.status_content - stream_selected = $("#broadcast_video").attr('video-type') == 'stream'; + stream_selected = $("#broadcast_video").data('videoType') == 'stream'; if data.streamer_status == 'recording' && data.status == 'active' && stream_selected $("#broadcast_video").html data.video_content new (Clappr.Player)( + <%= "baseUrl: 'http://cdn.clappr.io/latest'," if Rails.env.test? %> parentId: '#broadcast_video' source: data.full_live_stream_playback_url width: '100%', diff --git a/app/assets/javascripts/stream_player.js.erb b/app/assets/javascripts/stream_player.js.erb index 4a9f00d..a59e859 100644 --- a/app/assets/javascripts/stream_player.js.erb +++ b/app/assets/javascripts/stream_player.js.erb @@ -3,7 +3,7 @@ $(document).on("click", "[data-behavior=play_recording]", function() { return false; } - $("#broadcast_video").attr('video-type', 'recording'); + $("#broadcast_video").data('videoType', 'recording'); var playback_url = $(this).attr("data-playback-url") $("#broadcast_video").empty(); @@ -25,4 +25,4 @@ $(document).on("click", "[data-behavior=play_recording]", function() { $(this).prepend(' '); }); -$(document).on("click", "[data-behavior=play_stream]", function() { $("#broadcast_video").attr('video-type', 'stream'); }); \ No newline at end of file +$(document).on("click", "[data-behavior=play_stream]", function() { $("#broadcast_video").data('videoType', 'stream'); }); \ No newline at end of file diff --git a/app/controllers/broadcasts_controller.rb b/app/controllers/broadcasts_controller.rb index d778ba8..072498b 100644 --- a/app/controllers/broadcasts_controller.rb +++ b/app/controllers/broadcasts_controller.rb @@ -3,7 +3,7 @@ class BroadcastsController < ApplicationController before_action :set_project before_action :build_broadcast, only: [:new, :create] - before_action :set_broadcast, only: [:show, :destroy, :update] + before_action :set_broadcast, only: [:show, :destroy, :update, :destroy_file] before_action :set_multi_view_broadcasts, only: [:show] before_action :show_splash_screen, only: :index @@ -39,10 +39,7 @@ class BroadcastsController < ApplicationController end @broadcast.update(broadcast_params) - @files = @broadcast.files.order("created_at DESC").paginate(page: 1) - - pagination_content = ApplicationController.render html: helpers.will_paginate(@files, params: { active_tab: params[:active_tab], page: params[:page], active_files_tab: params[:active_files_tab] }) - BroadcastsChannel.broadcast_file_upload_updates(@broadcast, @files, pagination_content) + update_files_section end def destroy @@ -53,8 +50,23 @@ class BroadcastsController < ApplicationController end end + def destroy_file + authorize Broadcast + file = ActiveStorage::Attachment.find(params[:file_id]) + file.destroy + + update_files_section + end + private + def update_files_section + @files = @broadcast.files.order("created_at DESC").paginate(page: 1) + + pagination_content = ApplicationController.render html: helpers.will_paginate(@files, params: { active_tab: params[:active_tab], page: params[:page], active_files_tab: params[:active_files_tab] }) + BroadcastsChannel.broadcast_file_upload_updates(@broadcast, @files, pagination_content) + end + def show_splash_screen render :splash if broadcasts.count.zero? end 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/broadcast_policy.rb b/app/policies/broadcast_policy.rb index 1a9d9be..4c562e5 100644 --- a/app/policies/broadcast_policy.rb +++ b/app/policies/broadcast_policy.rb @@ -18,4 +18,12 @@ class BroadcastPolicy < ApplicationPolicy def update? true end + + def destroy_file? + if user.nil? || user.user.nil? + return false + end + + user.manager? || user.account_manager? + end end 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/broadcasts/_file.html.erb b/app/views/broadcasts/_file.html.erb index b0c90a8..f3b919d 100644 --- a/app/views/broadcasts/_file.html.erb +++ b/app/views/broadcasts/_file.html.erb @@ -1,12 +1,25 @@ -
  • - <% if file.variable? %> - <%= link_to image_tag(file.variant(resize_and_pad: [300, 300, background: "#F7F8F9"]), class: "bg-light img-thumbnail img-fluid"), file, target: "_blank" %> - <% else %> -
    - <%= link_to file, target: "_blank" do %> - <%= fa_icon("file", style: "font-size: 2rem") %> -
    <%= file.filename %>
    +
    + <% broadcast = file.record %> + <% show_delete = controller.class.module_parent.to_s == "Public" ? false : policy(broadcast).destroy_file? %> + <% file_class = show_delete ? "col-8" : "col-12" %> +
    +
  • + <% if file.variable? %> + <%= link_to image_tag(file.variant(resize_and_pad: [300, 300, background: "#F7F8F9"]), class: "bg-light img-thumbnail img-fluid"), file, target: "_blank" %> + <% else %> +
    + <%= link_to file, target: "_blank" do %> + <%= fa_icon("file", style: "font-size: 2rem") %> +
    <%= file.filename %>
    + <% end %> +
    <% end %> +
  • + + <% if show_delete %> +
    + <% url = url_for [:destroy_file, broadcast.project, broadcast, { file_id: file.id }] %> + <%= link_to fa_icon("trash fw", text: t('.actions.delete_file')), url, class: "btn btn-danger", remote: true, method: :delete, data: { confirm: t('.confirm_delete') } %>
    <% end %> - + \ No newline at end of file diff --git a/app/views/broadcasts/_video.html.erb b/app/views/broadcasts/_video.html.erb index 45fccca..9c44e2a 100644 --- a/app/views/broadcasts/_video.html.erb +++ b/app/views/broadcasts/_video.html.erb @@ -1,7 +1,7 @@ <% if broadcast.streamer_recording? && broadcast.active? %> -
    +
    <% else %> -
    +
    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 %> +
    @@ -47,4 +48,4 @@ - \ No newline at end of file + diff --git a/app/views/contracts/_amendment_page.html.erb b/app/views/contracts/_amendment_page.html.erb new file mode 100644 index 0000000..427dc9a --- /dev/null +++ b/app/views/contracts/_amendment_page.html.erb @@ -0,0 +1,19 @@ +<% if preview %> +

    PREVIEW ONLY

    +<% end %> + +

    <%= t '.heading' %>

    + +
    + <%= description_list_pair "#{t('.description_labels.amendment_clause')}:", releasable.contract_template.amendment_clause %> + <%= description_list_pair "#{t('.description_labels.amendment_signer_name')}:", releasable.amendment_signer_name %> + +
    <%= t('.description_labels.amendment_signature') %>:
    +
    + <% if preview %> + <%= image_tag dummy_signature %> + <% elsif releasable.amendment_signature.attached? %> + <%= image_tag releasable.amendment_signature.variant(auto_orient: true, resize: "200x200") %> + <% end %> +
    +
    \ No newline at end of file diff --git a/app/views/contracts/_signature_page.html.erb b/app/views/contracts/_signature_page.html.erb index 1f6265b..90727d7 100644 --- a/app/views/contracts/_signature_page.html.erb +++ b/app/views/contracts/_signature_page.html.erb @@ -18,10 +18,14 @@ <% end %> <% end %> - <%= description_list_pair_for releasable, :name, append: ":" %> - <%= description_list_pair "Contact Address:", releasable.contact_person.address %> - <%= description_list_pair "Contact Phone:", releasable.contact_person.phone %> - <%= description_list_pair "Contact Email:", releasable.contact_person.email %> + <%= description_list_pair t(".labels.#{releasable.model_name.param_key}.name", default: "Name"), releasable.name, append: ":" %> + <% if releasable.model_name == "LocationRelease" %> + <%= description_list_pair "Location Address:", releasable.address %> + <%= description_list_pair "Owner Name", releasable.person_name, append: ":" %> + <% end %> + <%= description_list_pair t(".labels.#{releasable.model_name.param_key}.contact_person_address", default: "Contact Address"), releasable.contact_person.address, append: ":" %> + <%= description_list_pair t(".labels.#{releasable.model_name.param_key}.contact_person_phone", default: "Contact Phone"), releasable.contact_person.phone, append: ":" %> + <%= description_list_pair t(".labels.#{releasable.model_name.param_key}.contact_person_email", default: "Contact Email"), releasable.contact_person.email, append: ":" %> <% if releasable.model_name == "AppearanceRelease" %> <%= description_list_pair "Person Date of Birth:", releasable&.person_date_of_birth&.strftime("%D") %> <% end %> diff --git a/app/views/contracts/pdf.html.erb b/app/views/contracts/pdf.html.erb index dd01e5f..edeab19 100644 --- a/app/views/contracts/pdf.html.erb +++ b/app/views/contracts/pdf.html.erb @@ -26,6 +26,12 @@ <%= render "contracts/signature_page", releasable: releasable, contract_template: contract_template, preview: preview %> +<% 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 @@
    + - + - - + + 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..7363cdd 100644 --- a/config/locales/en.yml +++ b/config/locales/en.yml @@ -214,6 +214,10 @@ en: destroy: alert: A live stream has been deleted api_error: Something went wrong, please try again later after some time + file: + actions: + delete_file: Delete + confirm_delete: Are you sure? index: actions: new: Create New Live Stream @@ -307,6 +311,7 @@ en: actions: book_demo: Schedule a Demo create_template: Create New Release Template + import_template: Import Template headings: benefits: Benefits how_it_works: How It Works @@ -323,6 +328,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 @@ -347,6 +358,12 @@ en: signature_page: heading: Signature Page instructions: "By signing this signature page, as of the date listed below, I hereby agree, acknowledge and accept the terms and conditions listed in this %{releasable_name}." + labels: + location_release: + contact_person_address: Owner Address + contact_person_email: Owner Email + contact_person_phone: Owner Phone + name: Location Name directories: destroy: alert: The folder has been deleted @@ -405,6 +422,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 @@ -772,7 +790,7 @@ en: table_headers: address: Address approved: Approved - name: Name + name: Location Name notes: Notes signed_at: Date Signed tags: Tags @@ -780,7 +798,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 +1048,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..a4a4688 100644 --- a/config/locales/es.yml +++ b/config/locales/es.yml @@ -81,6 +81,10 @@ es: do_not_copy_warning: "Do not copy (ES)" serial_number_label: "Serial Number (ES)" broadcasts: + file: + actions: + delete_file: Delete + confirm_delete: Are you sure? (ES) show: actions: reset_url: Reset URL (ES) @@ -148,6 +152,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 +217,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 +349,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 +401,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..4f0c3ff 100644 --- a/config/routes.rb +++ b/config/routes.rb @@ -96,6 +96,9 @@ Rails.application.routes.draw do end resources :projects, only: [] do resources :broadcasts, except: [:edit] do + member do + delete :destroy_file + end resource :zoom_meeting, only: [:show] end resources :directories, except: [:index] do @@ -128,7 +131,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/api/broadcasts_controller_spec.rb b/spec/controllers/api/broadcasts_controller_spec.rb index ee5e3af..5927bca 100644 --- a/spec/controllers/api/broadcasts_controller_spec.rb +++ b/spec/controllers/api/broadcasts_controller_spec.rb @@ -106,7 +106,7 @@ RSpec.describe Api::BroadcastsController, type: :controller do included = JSON.parse(response.body).dig('included') expect(relationships.keys).to include('files') - expect(included.size).to eq 1 + expect(included.size).to eq 3 expect(included.first.dig("id")).to eq broadcast.files.first.id.to_s expect(included.first.dig("type")).to eq 'active_storage_attachment' end diff --git a/spec/controllers/contract_templates_controller_spec.rb b/spec/controllers/contract_templates_controller_spec.rb index 6069598..b2a1af1 100644 --- a/spec/controllers/contract_templates_controller_spec.rb +++ b/spec/controllers/contract_templates_controller_spec.rb @@ -43,8 +43,21 @@ describe ContractTemplatesController do get :index, params: { project_id: project } expect(response.body).to have_link "Create New Release Template" + expect(response.body).to have_link "Import Template" expect(response.body).to have_link schedule_demo end + + context 'when current user is an associate' do + let(:current_user) { create(:user, :associate) } + + it 'does not show the new contract template button' do + get :index, params: { project_id: project } + + expect(response.body).not_to have_link "Create New Release Template" + expect(response.body).not_to have_link "Import Template" + expect(response.body).to have_link schedule_demo + end + end end context 'when current user is an associate' do 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/controllers/public/broadcasts_controller_spec.rb b/spec/controllers/public/broadcasts_controller_spec.rb index 8850bd7..f42338d 100644 --- a/spec/controllers/public/broadcasts_controller_spec.rb +++ b/spec/controllers/public/broadcasts_controller_spec.rb @@ -87,6 +87,7 @@ RSpec.describe Public::BroadcastsController, type: :controller do let!(:broadcast) { create(:broadcast, :with_stream, skip_create_callback: true, project: project ) } it "uploads files to broadcast" do + allow(BroadcastsChannel).to receive(:broadcast_file_upload_updates) patch :update, params: { token: broadcast.token, broadcast: file_params }, xhr: true expect(broadcast.files.count).to eq(1) diff --git a/spec/factories/broadcasts.rb b/spec/factories/broadcasts.rb index 3b022c2..4148242 100644 --- a/spec/factories/broadcasts.rb +++ b/spec/factories/broadcasts.rb @@ -17,7 +17,13 @@ FactoryBot.define do end trait :with_files do - files { [Rack::Test::UploadedFile.new('spec/fixtures/files/contract.pdf', 'application/pdf')] } + files do + [ + Rack::Test::UploadedFile.new('spec/fixtures/files/contract.pdf', 'application/pdf'), + Rack::Test::UploadedFile.new('spec/fixtures/files/audio.mp3', 'audio/mpeg'), + Rack::Test::UploadedFile.new('spec/fixtures/files/video_file.mp4', 'video/mp4') + ] + end end after(:build) do |broadcast, evaluator| 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..48ba336 100644 --- a/spec/features/user_manages_contract_templates_spec.rb +++ b/spec/features/user_manages_contract_templates_spec.rb @@ -11,11 +11,12 @@ RSpec.feature 'User manages contract templates', type: :feature do sign_in(current_user) end - scenario 'splash page is shown if tehre are no contract templates' do + scenario 'splash page is shown if there are no contract templates' do visit project_contract_templates_path(project) expect(page).to have_content schedule_demo expect(page).to have_content create_release_template + expect(page).to have_content import_release_template end scenario 'creating a new release template' do @@ -30,7 +31,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 +49,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 +91,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 +198,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 @@ -366,6 +379,7 @@ RSpec.feature 'User manages contract templates', type: :feature do expect(page).to have_content schedule_demo expect(page).not_to have_content create_release_template + expect(page).not_to have_content import_release_template end it 'does not show edit button' do @@ -397,11 +411,12 @@ RSpec.feature 'User manages contract templates', type: :feature do expect(page).to have_content('Delete') end - it 'does not show create release button on splash page' do + it 'shows create release button on splash page' do visit project_contract_templates_path(project) expect(page).to have_content schedule_demo expect(page).to have_content create_release_template + expect(page).to have_content import_release_template end it 'shows edit button when contract template is not signed' do @@ -465,6 +480,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 @@ -489,6 +508,10 @@ RSpec.feature 'User manages contract templates', type: :feature do t 'contract_templates.splash.actions.create_template' end + def import_release_template + t 'contract_templates.splash.actions.import_template' + end + def signature_legal_text_trix_field 'Signature legal text' end @@ -516,4 +539,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_broadcasts_spec.rb b/spec/features/user_managing_broadcasts_spec.rb index b20cabc..b4acf4e 100644 --- a/spec/features/user_managing_broadcasts_spec.rb +++ b/spec/features/user_managing_broadcasts_spec.rb @@ -93,7 +93,7 @@ feature 'User managing broadcasts' do BroadcastsChannel.broadcast_stream_updates(broadcast) expect(page).to have_content stream_begun_message - expect(page).to have_selector('div#broadcast_video', count: 1) + expect(page).to have_selector('div#broadcast_video', count: 2) broadcast.streamer_status = :idle broadcast.status = :idle @@ -164,6 +164,21 @@ feature 'User managing broadcasts' do click_on add_file_button end + scenario 'manager user can click delete button next to the file and delete file', js: true do + broadcast = create(:broadcast, :with_stream, :with_files, project: project) + + visit project_broadcast_path(project, broadcast) + + expect(page).to have_content delete_file_button, count: 3 + + accept_alert do + first('a', text: delete_file_button).click + end + + expect(page).to have_content delete_file_button, count: 2 + expect(Broadcast.find(broadcast.id).files.count).to eq 2 + end + scenario 'visit multi-view broadcast page', js: true do broadcast_one = create(:broadcast, :with_stream, :with_files, name: 'Broadcast 1', project: project) broadcast_two = create(:broadcast, :with_stream, :with_files, name: 'Broadcast 2', project: project) @@ -198,6 +213,14 @@ feature 'User managing broadcasts' do expect(page).to have_content schedule_demo expect(page).not_to have_content create_stream end + + scenario 'associate user does not see delete button next to the file', js: true do + broadcast = create(:broadcast, :with_stream, :with_files, project: project) + + visit project_broadcast_path(project, broadcast) + + expect(page).to have_content delete_file_button, count: 0 + end end context 'When the user is account manager' do @@ -209,6 +232,21 @@ feature 'User managing broadcasts' do expect(page).to have_content schedule_demo expect(page).to have_content create_stream end + + scenario 'account manager user can click delete button next to the file and delete file', js: true do + broadcast = create(:broadcast, :with_stream, :with_files, project: project) + + visit project_broadcast_path(project, broadcast) + + expect(page).to have_content delete_file_button, count: 3 + + accept_alert do + first('a', text: delete_file_button).click + end + + expect(page).to have_content delete_file_button, count: 2 + expect(Broadcast.find(broadcast.id).files.count).to eq 2 + end end end @@ -262,5 +300,9 @@ feature 'User managing broadcasts' do 'Live stream is waiting to begin' end + def delete_file_button + t 'broadcasts.file.actions.delete_file' + 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
    <%= 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..f319ea8 100644 --- a/app/views/location_releases/index.html.erb +++ b/app/views/location_releases/index.html.erb @@ -28,12 +28,12 @@
    <%= check_box_tag "location_release_ids[]", false, false %> <%= t '.table_headers.approved'%> <%= LocationRelease.human_attribute_name(:name) %><%= t(".table_headers.name") %> <%= t(".table_headers.address") %> <%= t(".table_headers.notes") %> <%= t(".table_headers.tags") %><%= t(".table_headers.signed_at") %><%= t(".table_headers.signed_at") %>