Compare commits
6 Commits
add-csv-to
...
allow-task
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
c17f41525d | ||
|
|
d12cec8487 | ||
|
|
bde18ab0f1 | ||
|
|
fc320a3421 | ||
|
|
7f49f31ebf | ||
|
|
4c49a5db03 |
@@ -33,6 +33,11 @@ class BroadcastsController < ApplicationController
|
|||||||
end
|
end
|
||||||
|
|
||||||
def update
|
def update
|
||||||
|
unless params.has_key?(:broadcast)
|
||||||
|
@broadcast.regenerate_token
|
||||||
|
redirect_to([@project, @broadcast], notice: t('.reset_notice')) and return
|
||||||
|
end
|
||||||
|
|
||||||
@broadcast.update(broadcast_params)
|
@broadcast.update(broadcast_params)
|
||||||
@files = @broadcast.files.order("created_at DESC").paginate(page: 1)
|
@files = @broadcast.files.order("created_at DESC").paginate(page: 1)
|
||||||
|
|
||||||
|
|||||||
@@ -66,7 +66,7 @@ class ContractTemplatesController < ApplicationController
|
|||||||
:signature_legal_text, :fee,
|
:signature_legal_text, :fee,
|
||||||
:applicable_medium_id, :applicable_medium_text,
|
:applicable_medium_id, :applicable_medium_text,
|
||||||
:territory_id, :territory_text,
|
:territory_id, :territory_text,
|
||||||
:term_id, :term_text,
|
:term_id, :term_text, :accessibility,
|
||||||
:restriction_id, :restriction_text,
|
:restriction_id, :restriction_text,
|
||||||
:question_1_text, :question_2_text,
|
:question_1_text, :question_2_text,
|
||||||
:question_3_text, :question_4_text,
|
:question_3_text, :question_4_text,
|
||||||
|
|||||||
@@ -28,8 +28,9 @@ class StreamNotificationsController < ApplicationController
|
|||||||
asset_uid = notification.dig(:object, :id)
|
asset_uid = notification.dig(:object, :id)
|
||||||
playback_uid = notification.dig(:data, :playback_ids, 0, :id)
|
playback_uid = notification.dig(:data, :playback_ids, 0, :id)
|
||||||
file_name = notification.dig(:data, :static_renditions, :files, -1, :name)
|
file_name = notification.dig(:data, :static_renditions, :files, -1, :name)
|
||||||
|
duration = notification.dig(:data, :duration)
|
||||||
|
|
||||||
recording = @broadcast.broadcast_recordings.create!(asset_uid: asset_uid, asset_playback_uid: playback_uid, file_name: file_name)
|
recording = @broadcast.broadcast_recordings.create!(asset_uid: asset_uid, asset_playback_uid: playback_uid, file_name: file_name, duration: duration)
|
||||||
recordings = @broadcast.broadcast_recordings.order_by_recent.paginate(page: params[:page])
|
recordings = @broadcast.broadcast_recordings.order_by_recent.paginate(page: params[:page])
|
||||||
|
|
||||||
link = helpers.link_to(recording.broadcast_name.titleize, recording.download_url, target: "_blank")
|
link = helpers.link_to(recording.broadcast_name.titleize, recording.download_url, target: "_blank")
|
||||||
|
|||||||
@@ -6,8 +6,8 @@ class GenerateContractsZipJob < ApplicationJob
|
|||||||
before_perform do |job|
|
before_perform do |job|
|
||||||
@project = job.arguments.first
|
@project = job.arguments.first
|
||||||
@download = job.arguments.second
|
@download = job.arguments.second
|
||||||
release_type = job.arguments.third
|
@release_type = job.arguments.third
|
||||||
@folder_name = "#{@project.name.parameterize}_#{get_release_name(release_type).gsub('_', '-')}"
|
@folder_name = "#{@project.name.parameterize}_#{get_release_name(@release_type).gsub('_', '-')}"
|
||||||
@download.update!(name: @folder_name, status: :pending)
|
@download.update!(name: @folder_name, status: :pending)
|
||||||
end
|
end
|
||||||
|
|
||||||
@@ -20,6 +20,11 @@ class GenerateContractsZipJob < ApplicationJob
|
|||||||
files.each do |attachment|
|
files.each do |attachment|
|
||||||
zipfile.add(attachment, File.join("#{dir}/", attachment))
|
zipfile.add(attachment, File.join("#{dir}/", attachment))
|
||||||
end
|
end
|
||||||
|
|
||||||
|
if @release_type.constantize.include?(CsvExportable)
|
||||||
|
csv_file = generate_csv releases
|
||||||
|
zipfile.get_output_stream("#{@folder_name}.csv") { |f| f.puts(csv_file) }
|
||||||
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
@download.file.attach(io: File.open(zipfile_name), filename: "#{@folder_name}.zip")
|
@download.file.attach(io: File.open(zipfile_name), filename: "#{@folder_name}.zip")
|
||||||
@@ -43,6 +48,19 @@ class GenerateContractsZipJob < ApplicationJob
|
|||||||
|
|
||||||
private
|
private
|
||||||
|
|
||||||
|
def generate_csv(releases)
|
||||||
|
release_class = @release_type.constantize
|
||||||
|
headers = release_class.csv_headers
|
||||||
|
|
||||||
|
CSV.generate(headers: true) do |csv|
|
||||||
|
csv << headers
|
||||||
|
releases.each do |release|
|
||||||
|
csv_row_data = release.to_csv_row
|
||||||
|
csv << csv_row_data
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
def get_release_name(release_type)
|
def get_release_name(release_type)
|
||||||
release_type.constantize.model_name.plural
|
release_type.constantize.model_name.plural
|
||||||
end
|
end
|
||||||
|
|||||||
@@ -9,6 +9,13 @@ class AcquiredMediaRelease < ApplicationRecord
|
|||||||
include Signable
|
include Signable
|
||||||
include Syncable
|
include Syncable
|
||||||
include PersonName
|
include PersonName
|
||||||
|
include CsvExportable
|
||||||
|
|
||||||
|
class << self
|
||||||
|
def custom_csv_exportable_headers
|
||||||
|
%i[name file_infos_count]
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
has_many :file_infos, as: :releasable, dependent: :destroy
|
has_many :file_infos, as: :releasable, dependent: :destroy
|
||||||
|
|
||||||
@@ -57,4 +64,8 @@ class AcquiredMediaRelease < ApplicationRecord
|
|||||||
def uses_edl?
|
def uses_edl?
|
||||||
true
|
true
|
||||||
end
|
end
|
||||||
|
|
||||||
|
def file_infos_count
|
||||||
|
file_infos.any? ? file_infos.size : I18n.t('acquired_media_releases.acquired_media_release.no_media')
|
||||||
|
end
|
||||||
end
|
end
|
||||||
|
|||||||
@@ -15,6 +15,13 @@ class AppearanceRelease < ApplicationRecord
|
|||||||
include SecondGuardianPhotoable
|
include SecondGuardianPhotoable
|
||||||
include GuardianName
|
include GuardianName
|
||||||
include SecondGuardianName
|
include SecondGuardianName
|
||||||
|
include CsvExportable
|
||||||
|
|
||||||
|
class << self
|
||||||
|
def custom_csv_exportable_headers
|
||||||
|
%i[name contact_info]
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
has_one_attached :person_photo
|
has_one_attached :person_photo
|
||||||
|
|
||||||
|
|||||||
56
app/models/concerns/csv_exportable.rb
Normal file
56
app/models/concerns/csv_exportable.rb
Normal file
@@ -0,0 +1,56 @@
|
|||||||
|
# frozen_string_literal: true
|
||||||
|
|
||||||
|
module CsvExportable
|
||||||
|
extend ActiveSupport::Concern
|
||||||
|
|
||||||
|
COMMON_HEADERS = %i[notes tags signed_at].freeze
|
||||||
|
COMMON_VALUES = %w[clean_notes clean_tags signed_on].freeze
|
||||||
|
|
||||||
|
included do
|
||||||
|
class << self
|
||||||
|
def custom_csv_exportable_headers
|
||||||
|
[]
|
||||||
|
end
|
||||||
|
|
||||||
|
def csv_headers
|
||||||
|
headers = custom_csv_exportable_headers + COMMON_HEADERS
|
||||||
|
|
||||||
|
headers.map do |header|
|
||||||
|
I18n.t("#{model_name.plural}.index.table_headers.#{header}")
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
def to_csv_row
|
||||||
|
(self.class.custom_csv_exportable_headers + COMMON_VALUES).map do |function|
|
||||||
|
send(function)
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
private
|
||||||
|
|
||||||
|
def contact_info
|
||||||
|
contact_info = ''
|
||||||
|
contact_info += "#{person_address}; " if person_address.present?
|
||||||
|
contact_info += "P: #{person_phone}; " if person_phone.present?
|
||||||
|
contact_info += "E: #{person_email}" if person_email.present?
|
||||||
|
contact_info.delete_suffix '; '
|
||||||
|
end
|
||||||
|
|
||||||
|
def clean_notes
|
||||||
|
notes = ''
|
||||||
|
self.notes.order_by_recent.each do |note|
|
||||||
|
notes += "#{note.content}(#{note.email}), "
|
||||||
|
end
|
||||||
|
notes.delete_suffix ', '
|
||||||
|
end
|
||||||
|
|
||||||
|
def clean_tags
|
||||||
|
tags = ''
|
||||||
|
self.tags.each do |tag|
|
||||||
|
tags += "#{tag.name}, "
|
||||||
|
end
|
||||||
|
tags.delete_suffix ', '
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
@@ -43,6 +43,8 @@ class ContractTemplate < ApplicationRecord
|
|||||||
scope :non_archived, -> { where(archived_at: nil) }
|
scope :non_archived, -> { where(archived_at: nil) }
|
||||||
scope :order_by_name, -> { order(:name) }
|
scope :order_by_name, -> { order(:name) }
|
||||||
|
|
||||||
|
enum accessibility: [:public_template, :private_template]
|
||||||
|
|
||||||
def fee?
|
def fee?
|
||||||
!fee.zero?
|
!fee.zero?
|
||||||
end
|
end
|
||||||
@@ -66,4 +68,10 @@ class ContractTemplate < ApplicationRecord
|
|||||||
def has_questionnaire?
|
def has_questionnaire?
|
||||||
(1..NUMBER_OF_CUSTOM_FIELDS).any? { |n| public_send("question_#{n}_text").presence }
|
(1..NUMBER_OF_CUSTOM_FIELDS).any? { |n| public_send("question_#{n}_text").presence }
|
||||||
end
|
end
|
||||||
|
|
||||||
|
def attributes
|
||||||
|
result = super()
|
||||||
|
result[:signature_legal_text] = signature_legal_text.as_json
|
||||||
|
result
|
||||||
|
end
|
||||||
end
|
end
|
||||||
|
|||||||
@@ -10,6 +10,13 @@ class LocationRelease < ApplicationRecord
|
|||||||
include Syncable
|
include Syncable
|
||||||
include Taggable
|
include Taggable
|
||||||
include PersonName
|
include PersonName
|
||||||
|
include CsvExportable
|
||||||
|
|
||||||
|
class << self
|
||||||
|
def custom_csv_exportable_headers
|
||||||
|
%i[name address]
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
composed_of :address,
|
composed_of :address,
|
||||||
mapping: [
|
mapping: [
|
||||||
|
|||||||
@@ -10,6 +10,13 @@ class MaterialRelease < ApplicationRecord
|
|||||||
include Syncable
|
include Syncable
|
||||||
include Taggable
|
include Taggable
|
||||||
include PersonName
|
include PersonName
|
||||||
|
include CsvExportable
|
||||||
|
|
||||||
|
class << self
|
||||||
|
def custom_csv_exportable_headers
|
||||||
|
%i[name]
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
composed_of :person_address,
|
composed_of :person_address,
|
||||||
class_name: "Address",
|
class_name: "Address",
|
||||||
|
|||||||
@@ -11,6 +11,13 @@ class MedicalRelease < ApplicationRecord
|
|||||||
include SecondGuardianPhotoable
|
include SecondGuardianPhotoable
|
||||||
include GuardianName
|
include GuardianName
|
||||||
include SecondGuardianName
|
include SecondGuardianName
|
||||||
|
include CsvExportable
|
||||||
|
|
||||||
|
class << self
|
||||||
|
def custom_csv_exportable_headers
|
||||||
|
%i[approved? name contact_info]
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
NUMBER_OF_CUSTOM_FIELDS = 15
|
NUMBER_OF_CUSTOM_FIELDS = 15
|
||||||
|
|
||||||
|
|||||||
@@ -9,6 +9,13 @@ class MiscRelease < ApplicationRecord
|
|||||||
include PersonName
|
include PersonName
|
||||||
include GuardianName
|
include GuardianName
|
||||||
include GuardianPhotoable
|
include GuardianPhotoable
|
||||||
|
include CsvExportable
|
||||||
|
|
||||||
|
class << self
|
||||||
|
def custom_csv_exportable_headers
|
||||||
|
%i[name contact_info]
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
NUMBER_OF_CUSTOM_FIELDS = 15
|
NUMBER_OF_CUSTOM_FIELDS = 15
|
||||||
|
|
||||||
|
|||||||
@@ -7,6 +7,13 @@ class MusicRelease < ApplicationRecord
|
|||||||
include Searchable
|
include Searchable
|
||||||
include Taggable
|
include Taggable
|
||||||
include PersonName
|
include PersonName
|
||||||
|
include CsvExportable
|
||||||
|
|
||||||
|
class << self
|
||||||
|
def custom_csv_exportable_headers
|
||||||
|
%i[name file_infos_count composers_count publishers_count]
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
has_many :file_infos, as: :releasable, dependent: :destroy
|
has_many :file_infos, as: :releasable, dependent: :destroy
|
||||||
has_many :composers, dependent: :destroy
|
has_many :composers, dependent: :destroy
|
||||||
@@ -72,6 +79,18 @@ class MusicRelease < ApplicationRecord
|
|||||||
false
|
false
|
||||||
end
|
end
|
||||||
|
|
||||||
|
def file_infos_count
|
||||||
|
file_infos.size
|
||||||
|
end
|
||||||
|
|
||||||
|
def composers_count
|
||||||
|
composers.size
|
||||||
|
end
|
||||||
|
|
||||||
|
def publishers_count
|
||||||
|
publishers.size
|
||||||
|
end
|
||||||
|
|
||||||
private
|
private
|
||||||
|
|
||||||
def publisher_percentages_add_up_to_100
|
def publisher_percentages_add_up_to_100
|
||||||
|
|||||||
@@ -14,6 +14,13 @@ class TalentRelease < ApplicationRecord
|
|||||||
include SecondGuardianPhotoable
|
include SecondGuardianPhotoable
|
||||||
include GuardianName
|
include GuardianName
|
||||||
include SecondGuardianName
|
include SecondGuardianName
|
||||||
|
include CsvExportable
|
||||||
|
|
||||||
|
class << self
|
||||||
|
def custom_csv_exportable_headers
|
||||||
|
%i[name phone email]
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
composed_of :person_address,
|
composed_of :person_address,
|
||||||
class_name: "Address",
|
class_name: "Address",
|
||||||
@@ -86,6 +93,14 @@ class TalentRelease < ApplicationRecord
|
|||||||
person_name
|
person_name
|
||||||
end
|
end
|
||||||
|
|
||||||
|
def phone
|
||||||
|
person_phone
|
||||||
|
end
|
||||||
|
|
||||||
|
def email
|
||||||
|
person_email
|
||||||
|
end
|
||||||
|
|
||||||
def filename_suffix
|
def filename_suffix
|
||||||
"#{person_last_name} #{person_first_name}"
|
"#{person_last_name} #{person_first_name}"
|
||||||
end
|
end
|
||||||
|
|||||||
@@ -6,5 +6,5 @@ class TaskRequest < ApplicationRecord
|
|||||||
|
|
||||||
scope :order_by_recent, -> { order(created_at: :desc) }
|
scope :order_by_recent, -> { order(created_at: :desc) }
|
||||||
|
|
||||||
validates :time_allowed, numericality: { only_integer: true, greater_than_or_equal_to: 2 }
|
validates :time_allowed, numericality: { only_integer: true, greater_than_or_equal_to: 2 }, allow_blank: true
|
||||||
end
|
end
|
||||||
|
|||||||
@@ -3,8 +3,10 @@ class ContractTemplatePolicy < ApplicationPolicy
|
|||||||
def resolve
|
def resolve
|
||||||
if user.account_manager?
|
if user.account_manager?
|
||||||
scope.left_outer_joins(:project).where(projects: {account: user.account})
|
scope.left_outer_joins(:project).where(projects: {account: user.account})
|
||||||
else
|
elsif user.manager?
|
||||||
scope.left_outer_joins(project: :project_memberships).where(project_memberships: { user_id: user.id })
|
scope.left_outer_joins(project: :project_memberships).where(project_memberships: { user_id: user.id })
|
||||||
|
else
|
||||||
|
scope.public_template.left_outer_joins(project: :project_memberships).where(project_memberships: { user_id: user.id })
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|||||||
@@ -102,6 +102,7 @@
|
|||||||
<i class="fa fa-clipboard"></i>
|
<i class="fa fa-clipboard"></i>
|
||||||
Copy URL
|
Copy URL
|
||||||
</button>
|
</button>
|
||||||
|
<%= link_to t('.actions.reset_url'), [@project, @broadcast], method: :patch, class: "btn btn-danger" %>
|
||||||
</div>
|
</div>
|
||||||
<% else %>
|
<% else %>
|
||||||
<input type="text" class="form-control" value="<%= broadcast_url(@broadcast.token) %>" readonly>
|
<input type="text" class="form-control" value="<%= broadcast_url(@broadcast.token) %>" readonly>
|
||||||
@@ -110,6 +111,7 @@
|
|||||||
<i class="fa fa-clipboard"></i>
|
<i class="fa fa-clipboard"></i>
|
||||||
Copy URL
|
Copy URL
|
||||||
</button>
|
</button>
|
||||||
|
<%= link_to t('.actions.reset_url'), [@project, @broadcast], method: :patch, class: "btn btn-danger" %>
|
||||||
</div>
|
</div>
|
||||||
<% end %>
|
<% end %>
|
||||||
</div>
|
</div>
|
||||||
|
|||||||
@@ -4,6 +4,10 @@
|
|||||||
<%= form.text_field :name, wrapper_class: "col-sm-6" %>
|
<%= 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) } }, class: "form-control custom-select" %>
|
||||||
</div>
|
</div>
|
||||||
|
<div class="form-row mb-3">
|
||||||
|
<%= form.radio_button :accessibility, :public_template, label: "Public", wrapper_class: "mr-3" %>
|
||||||
|
<%= form.radio_button :accessibility, :private_template, label: "Private" %>
|
||||||
|
</div>
|
||||||
<div class="form-row" id="fee_field">
|
<div class="form-row" id="fee_field">
|
||||||
<%= form.number_field :fee, min:"0", max:"99999999", step: "0.01", prepend: "$", wrapper_class: "col-sm-6" %>
|
<%= form.number_field :fee, min:"0", max:"99999999", step: "0.01", prepend: "$", wrapper_class: "col-sm-6" %>
|
||||||
</div>
|
</div>
|
||||||
|
|||||||
@@ -1,9 +1,19 @@
|
|||||||
<%= errors_summary_for task_request %>
|
<%= errors_summary_for task_request %>
|
||||||
|
|
||||||
<%= bootstrap_form_with model: model, url: [@project, @task_request, show_chat: true], local: true do |form| %>
|
<%= bootstrap_form_with model: model, url: [@project, @task_request, show_chat: true], local: true do |form| %>
|
||||||
<div class="alert alert-info text-center text-md-left">
|
|
||||||
<%= fa_icon "info-circle" %>
|
<div class="d-flex">
|
||||||
<strong><%= t '.info_message' %></strong>
|
<div class="row">
|
||||||
|
<div class="col-xl-10 col-12">
|
||||||
|
<div class="alert alert-info text-center text-md-left">
|
||||||
|
<%= fa_icon "info-circle" %>
|
||||||
|
<strong><%= t '.info_message' %></strong>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<div class="col-xl-2 col-12">
|
||||||
|
<%= form.submit t('.actions.chat_now'), class: "btn btn-block btn-warning pt-4 pb-4 mb-1", data: { disable_with: t("shared.disable_with") } %>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<%= form.text_area :description, label: t('.labels.description') %>
|
<%= form.text_area :description, label: t('.labels.description') %>
|
||||||
|
|||||||
@@ -50,6 +50,7 @@ en:
|
|||||||
empty: Acquired Media Releases will appear here
|
empty: Acquired Media Releases will appear here
|
||||||
table_headers:
|
table_headers:
|
||||||
file_infos_count: No. Files
|
file_infos_count: No. Files
|
||||||
|
name: Name
|
||||||
notes: Notes
|
notes: Notes
|
||||||
signed_at: Date Signed
|
signed_at: Date Signed
|
||||||
tags: Tags
|
tags: Tags
|
||||||
@@ -151,6 +152,8 @@ en:
|
|||||||
empty: Appearance Releases will appear here
|
empty: Appearance Releases will appear here
|
||||||
imported_appearance_release_missing_attachment: Person photo or contract missing for imported appearance release
|
imported_appearance_release_missing_attachment: Person photo or contract missing for imported appearance release
|
||||||
table_headers:
|
table_headers:
|
||||||
|
contact_info: Contact info
|
||||||
|
name: Name
|
||||||
notes: Notes
|
notes: Notes
|
||||||
signed_at: Date Signed
|
signed_at: Date Signed
|
||||||
tags: Tags
|
tags: Tags
|
||||||
@@ -214,6 +217,9 @@ en:
|
|||||||
new:
|
new:
|
||||||
heading:
|
heading:
|
||||||
Create Live Stream
|
Create Live Stream
|
||||||
|
show:
|
||||||
|
actions:
|
||||||
|
reset_url: Reset URL
|
||||||
splash:
|
splash:
|
||||||
actions:
|
actions:
|
||||||
book_demo: Schedule a Demo
|
book_demo: Schedule a Demo
|
||||||
@@ -232,6 +238,8 @@ en:
|
|||||||
share_stream: Share live stream link with clients
|
share_stream: Share live stream link with clients
|
||||||
stream_from_mobile_app: Stream from ME Suite Mobile app, or via a professional camera
|
stream_from_mobile_app: Stream from ME Suite Mobile app, or via a professional camera
|
||||||
stream_multiple_cameras: Stream multiple cameras at one time
|
stream_multiple_cameras: Stream multiple cameras at one time
|
||||||
|
update:
|
||||||
|
reset_notice: The Share URL has been reset, and the previous URL will no longer work. Please click "Copy URL" and share it again with those who you want to have access to this live stream
|
||||||
bulk_taggings:
|
bulk_taggings:
|
||||||
new_bulk_tag_modal:
|
new_bulk_tag_modal:
|
||||||
submit: Add
|
submit: Add
|
||||||
@@ -742,6 +750,7 @@ en:
|
|||||||
empty: Location Releases will appear here
|
empty: Location Releases will appear here
|
||||||
table_headers:
|
table_headers:
|
||||||
address: Address
|
address: Address
|
||||||
|
name: Name
|
||||||
notes: Notes
|
notes: Notes
|
||||||
signed_at: Date Signed
|
signed_at: Date Signed
|
||||||
tags: Tags
|
tags: Tags
|
||||||
@@ -776,6 +785,7 @@ en:
|
|||||||
search: Search
|
search: Search
|
||||||
empty: Material Releases will appear here
|
empty: Material Releases will appear here
|
||||||
table_headers:
|
table_headers:
|
||||||
|
name: Name
|
||||||
notes: Notes
|
notes: Notes
|
||||||
signed_at: Date Signed
|
signed_at: Date Signed
|
||||||
tags: Tags
|
tags: Tags
|
||||||
@@ -798,6 +808,9 @@ en:
|
|||||||
empty: Medical releases will appear here
|
empty: Medical releases will appear here
|
||||||
table_headers:
|
table_headers:
|
||||||
approved: Approved
|
approved: Approved
|
||||||
|
approved?: Approved
|
||||||
|
contact_info: Contact info
|
||||||
|
name: Person name
|
||||||
notes: Notes
|
notes: Notes
|
||||||
signed_at: Date Signed
|
signed_at: Date Signed
|
||||||
tags: Tags
|
tags: Tags
|
||||||
@@ -815,6 +828,8 @@ en:
|
|||||||
search: Search
|
search: Search
|
||||||
empty: Misc Releases will appear here
|
empty: Misc Releases will appear here
|
||||||
table_headers:
|
table_headers:
|
||||||
|
contact_info: Contact info
|
||||||
|
name: Person name
|
||||||
notes: Notes
|
notes: Notes
|
||||||
signed_at: Date Signed
|
signed_at: Date Signed
|
||||||
tags: Tags
|
tags: Tags
|
||||||
@@ -849,6 +864,7 @@ en:
|
|||||||
table_headers:
|
table_headers:
|
||||||
composers_count: No. Composers
|
composers_count: No. Composers
|
||||||
file_infos_count: No. Files
|
file_infos_count: No. Files
|
||||||
|
name: Name
|
||||||
notes: Notes
|
notes: Notes
|
||||||
publishers_count: No. Publishers
|
publishers_count: No. Publishers
|
||||||
signed_at: Date Signed
|
signed_at: Date Signed
|
||||||
@@ -1245,7 +1261,10 @@ en:
|
|||||||
search: Search
|
search: Search
|
||||||
empty: Talent Releases will appear here
|
empty: Talent Releases will appear here
|
||||||
table_headers:
|
table_headers:
|
||||||
|
email: Email
|
||||||
|
name: Name
|
||||||
notes: Notes
|
notes: Notes
|
||||||
|
phone: Phone
|
||||||
signed_at: Date Signed
|
signed_at: Date Signed
|
||||||
tags: Tags
|
tags: Tags
|
||||||
new:
|
new:
|
||||||
@@ -1265,7 +1284,9 @@ en:
|
|||||||
heading:
|
heading:
|
||||||
Edit Task Request
|
Edit Task Request
|
||||||
form:
|
form:
|
||||||
info_message: After submitting this task request, you'll be connected via chat with a ME Suite representative.
|
actions:
|
||||||
|
chat_now: Chat Now
|
||||||
|
info_message: For best results, please fill out this form prior to being connected with a TaskME assistant. However, if urgent, you can start speaking with a TaskME assistant by pressing the Chat Now button to the right
|
||||||
labels:
|
labels:
|
||||||
additional_notes: Please add any additional notes we should be aware of regarding this task.
|
additional_notes: Please add any additional notes we should be aware of regarding this task.
|
||||||
deadline: What is the deadline for this task?
|
deadline: What is the deadline for this task?
|
||||||
|
|||||||
@@ -1,4 +1,14 @@
|
|||||||
es:
|
es:
|
||||||
|
acquired_media_releases:
|
||||||
|
acquired_media_release:
|
||||||
|
no_media: No Media (ES)
|
||||||
|
index:
|
||||||
|
table_headers:
|
||||||
|
file_infos_count: No. Files (ES)
|
||||||
|
name: Name (ES)
|
||||||
|
notes: Notes (ES)
|
||||||
|
signed_at: Date Signed (ES)
|
||||||
|
tags: Tags (ES)
|
||||||
activerecord:
|
activerecord:
|
||||||
attributes:
|
attributes:
|
||||||
appearance_release:
|
appearance_release:
|
||||||
@@ -41,6 +51,12 @@ es:
|
|||||||
heading: Person Photo (ES)
|
heading: Person Photo (ES)
|
||||||
index:
|
index:
|
||||||
imported_appearance_release_missing_attachment: Person photo or contract missing for imported appearance release (ES)
|
imported_appearance_release_missing_attachment: Person photo or contract missing for imported appearance release (ES)
|
||||||
|
table_headers:
|
||||||
|
contact_info: ""
|
||||||
|
name: ""
|
||||||
|
notes: ""
|
||||||
|
signed_at: ""
|
||||||
|
tags: ""
|
||||||
shared:
|
shared:
|
||||||
imported_appearance_release_contract_name: Contrato Importado
|
imported_appearance_release_contract_name: Contrato Importado
|
||||||
imported_appearance_release_headshot_name: Retrato Importado
|
imported_appearance_release_headshot_name: Retrato Importado
|
||||||
@@ -65,6 +81,9 @@ es:
|
|||||||
do_not_copy_warning: "Do not copy (ES)"
|
do_not_copy_warning: "Do not copy (ES)"
|
||||||
serial_number_label: "Serial Number (ES)"
|
serial_number_label: "Serial Number (ES)"
|
||||||
broadcasts:
|
broadcasts:
|
||||||
|
show:
|
||||||
|
actions:
|
||||||
|
reset_url: Reset URL (ES)
|
||||||
splash:
|
splash:
|
||||||
actions:
|
actions:
|
||||||
book_demo: Schedule a Demo
|
book_demo: Schedule a Demo
|
||||||
@@ -83,6 +102,8 @@ es:
|
|||||||
share_stream: Share live stream link with clients
|
share_stream: Share live stream link with clients
|
||||||
stream_from_mobile_app: Stream from ME Suite Mobile app, or via a professional camera
|
stream_from_mobile_app: Stream from ME Suite Mobile app, or via a professional camera
|
||||||
stream_multiple_cameras: Stream multiple cameras at one time
|
stream_multiple_cameras: Stream multiple cameras at one time
|
||||||
|
update:
|
||||||
|
reset_notice: The Share URL has been reset, and the previous URL will no longer work. Please click "Copy URL" and share it again with those who you want to have access to this live stream
|
||||||
contract_templates:
|
contract_templates:
|
||||||
blank_contracts:
|
blank_contracts:
|
||||||
create:
|
create:
|
||||||
@@ -296,21 +317,57 @@ es:
|
|||||||
form:
|
form:
|
||||||
photos:
|
photos:
|
||||||
dropzone_label: Tap to take a photo of the Property (optional) (ES)
|
dropzone_label: Tap to take a photo of the Property (optional) (ES)
|
||||||
|
index:
|
||||||
|
table_headers:
|
||||||
|
address: Address (ES)
|
||||||
|
notes: Notes (ES)
|
||||||
|
signed_at: Date Signed (ES)
|
||||||
|
tags: Tags (ES)
|
||||||
material_releases:
|
material_releases:
|
||||||
form:
|
form:
|
||||||
photos:
|
photos:
|
||||||
dropzone_label: Tap to take a photo of Licensed Material (optional) (ES)
|
dropzone_label: Tap to take a photo of Licensed Material (optional) (ES)
|
||||||
|
index:
|
||||||
|
table_headers:
|
||||||
|
name: Name (ES)
|
||||||
|
notes: Notes (ES)
|
||||||
|
signed_at: Date Signed (ES)
|
||||||
|
tags: Tags (ES)
|
||||||
medical_releases:
|
medical_releases:
|
||||||
custom_validation_errors:
|
custom_validation_errors:
|
||||||
question_answer_is_required: answer is required (ES)
|
question_answer_is_required: answer is required (ES)
|
||||||
index:
|
index:
|
||||||
table_headers:
|
table_headers:
|
||||||
approved: Approved (ES)
|
approved: Approved (ES)
|
||||||
|
approved?: Approved (ES)
|
||||||
|
contact_info: Contact info (ES)
|
||||||
|
name: Person name (ES)
|
||||||
|
notes: Notes (ES)
|
||||||
|
signed_at: Date Signed (ES)
|
||||||
|
tags: Tags (ES)
|
||||||
medical_release:
|
medical_release:
|
||||||
actions:
|
actions:
|
||||||
review: Review (ES)
|
review: Review (ES)
|
||||||
messages:
|
messages:
|
||||||
approved_tooltip: ""
|
approved_tooltip: ""
|
||||||
|
misc_releases:
|
||||||
|
index:
|
||||||
|
table_headers:
|
||||||
|
contact_info: Contact info (ES)
|
||||||
|
name: Person name (ES)
|
||||||
|
notes: Notes (ES)
|
||||||
|
signed_at: Date Signed (ES)
|
||||||
|
tags: Tags (ES)
|
||||||
|
music_releases:
|
||||||
|
index:
|
||||||
|
table_headers:
|
||||||
|
composers_count: No. Composers (ES)
|
||||||
|
file_infos_count: No. Files (ES)
|
||||||
|
name: Name (ES)
|
||||||
|
notes: Notes (ES)
|
||||||
|
publishers_count: No. Publishers (ES)
|
||||||
|
signed_at: Date Signed (ES)
|
||||||
|
tags: Tags (ES)
|
||||||
public:
|
public:
|
||||||
appearance_releases:
|
appearance_releases:
|
||||||
create:
|
create:
|
||||||
@@ -415,11 +472,21 @@ es:
|
|||||||
heading: Second Guardian Photo (ES)
|
heading: Second Guardian Photo (ES)
|
||||||
guardian_photo:
|
guardian_photo:
|
||||||
heading: Guardian Photo (ES)
|
heading: Guardian Photo (ES)
|
||||||
|
index:
|
||||||
|
table_headers:
|
||||||
|
email: Email (ES)
|
||||||
|
name: Name (ES)
|
||||||
|
notes: Notes (ES)
|
||||||
|
phone: Phone (ES)
|
||||||
|
signed_at: Date Signed (ES)
|
||||||
|
tags: Tags (ES)
|
||||||
task_requests:
|
task_requests:
|
||||||
create:
|
create:
|
||||||
success_message: Your task request was successfully submitted. Thank you. A chat window will pop up on the lower right in a few seconds. (ES)
|
success_message: Your task request was successfully submitted. Thank you. A chat window will pop up on the lower right in a few seconds. (ES)
|
||||||
form:
|
form:
|
||||||
info_message: After submitting this task request, you'll be connected via chat with a ME Suite representative. (ES)
|
actions:
|
||||||
|
chat_now: Chat Now (ES)
|
||||||
|
info_message: For best results, please fill out this form prior to being connected with a TaskME assistant. However, if urgent, you can start speaking with a TaskME assistant by pressing the Chat Now button to the right (ES)
|
||||||
index:
|
index:
|
||||||
table_headers:
|
table_headers:
|
||||||
task_request_description: Description (ES)
|
task_request_description: Description (ES)
|
||||||
|
|||||||
@@ -0,0 +1,18 @@
|
|||||||
|
class AddDurationToBroadcastRecordings < ActiveRecord::DataMigration
|
||||||
|
def up
|
||||||
|
recordings = BroadcastRecording.where(duration: nil)
|
||||||
|
client = MuxRuby::AssetsApi.new
|
||||||
|
|
||||||
|
recordings.each do |recording|
|
||||||
|
begin
|
||||||
|
response = client.get_asset(recording.asset_uid)
|
||||||
|
duration = response.data.duration
|
||||||
|
recording.update(duration: duration)
|
||||||
|
rescue MuxRuby::ApiError => e
|
||||||
|
Rails.logger.error("Failed to update duration for broadcast recording with id #{recording.id}\n" + e.message)
|
||||||
|
end
|
||||||
|
|
||||||
|
sleep(1)
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
@@ -0,0 +1,5 @@
|
|||||||
|
class AddAccessibilityToContractTemplates < ActiveRecord::Migration[6.0]
|
||||||
|
def change
|
||||||
|
add_column :contract_templates, :accessibility, :integer, default: 0
|
||||||
|
end
|
||||||
|
end
|
||||||
@@ -0,0 +1,5 @@
|
|||||||
|
class AddDurationToBroadcastRecordings < ActiveRecord::Migration[6.0]
|
||||||
|
def change
|
||||||
|
add_column :broadcast_recordings, :duration, :float
|
||||||
|
end
|
||||||
|
end
|
||||||
@@ -494,7 +494,8 @@ CREATE TABLE public.broadcast_recordings (
|
|||||||
asset_playback_uid character varying NOT NULL,
|
asset_playback_uid character varying NOT NULL,
|
||||||
file_name character varying NOT NULL,
|
file_name character varying NOT NULL,
|
||||||
created_at timestamp(6) without time zone NOT NULL,
|
created_at timestamp(6) without time zone NOT NULL,
|
||||||
updated_at timestamp(6) without time zone NOT NULL
|
updated_at timestamp(6) without time zone NOT NULL,
|
||||||
|
duration double precision
|
||||||
);
|
);
|
||||||
|
|
||||||
|
|
||||||
@@ -629,7 +630,8 @@ CREATE TABLE public.contract_templates (
|
|||||||
question_12_text text,
|
question_12_text text,
|
||||||
question_13_text text,
|
question_13_text text,
|
||||||
question_14_text text,
|
question_14_text text,
|
||||||
question_15_text text
|
question_15_text text,
|
||||||
|
accessibility integer DEFAULT 0
|
||||||
);
|
);
|
||||||
|
|
||||||
|
|
||||||
@@ -3906,6 +3908,8 @@ INSERT INTO "schema_migrations" (version) VALUES
|
|||||||
('20200622180507'),
|
('20200622180507'),
|
||||||
('20200625144713'),
|
('20200625144713'),
|
||||||
('20200702152130'),
|
('20200702152130'),
|
||||||
('20200707155717');
|
('20200707155717'),
|
||||||
|
('20200709120630'),
|
||||||
|
('20200712181139');
|
||||||
|
|
||||||
|
|
||||||
|
|||||||
@@ -30,6 +30,21 @@ RSpec.describe Api::ContractTemplatesController, type: :controller do
|
|||||||
|
|
||||||
expect(response).to be_successful
|
expect(response).to be_successful
|
||||||
end
|
end
|
||||||
|
|
||||||
|
it 'returns electronic signature legal text when present' do
|
||||||
|
ct = create(:contract_template, name: 'ct1', project_id: project.id)
|
||||||
|
ct.signature_legal_text = "some electronic signature legal text"
|
||||||
|
ct.save
|
||||||
|
|
||||||
|
sign_in_to_api(current_user)
|
||||||
|
get :show, params: { id: ct.id }
|
||||||
|
|
||||||
|
expect(response).to be_successful
|
||||||
|
|
||||||
|
expect(response.body).to include("signature_legal_text")
|
||||||
|
expect(response.body).to include(ct.signature_legal_text.body.as_json)
|
||||||
|
end
|
||||||
|
|
||||||
end
|
end
|
||||||
|
|
||||||
private
|
private
|
||||||
|
|||||||
@@ -127,9 +127,16 @@ RSpec.describe Api::SyncController, type: :controller do
|
|||||||
get :index
|
get :index
|
||||||
|
|
||||||
medical_releases = attributes_for_type('medical_releases')
|
medical_releases = attributes_for_type('medical_releases')
|
||||||
|
|
||||||
expect(medical_releases.first).to include('id')
|
expect(medical_releases.first).to include('id')
|
||||||
end
|
end
|
||||||
|
|
||||||
|
it 'contains signature legal text for contract templates' do
|
||||||
|
create_default_data_with_signature_legal_text
|
||||||
|
get :index
|
||||||
|
contract_templates = attributes_for_type('contract_templates')
|
||||||
|
expect(contract_templates.first).to include('signature_legal_text')
|
||||||
|
expect(contract_templates.first['signature_legal_text']).to eq ContractTemplate.first.signature_legal_text.as_json
|
||||||
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
private
|
private
|
||||||
@@ -149,6 +156,13 @@ RSpec.describe Api::SyncController, type: :controller do
|
|||||||
create(:appearance_release, :minor_with_guardian_photo, project: project)
|
create(:appearance_release, :minor_with_guardian_photo, project: project)
|
||||||
end
|
end
|
||||||
|
|
||||||
|
def create_default_data_with_signature_legal_text
|
||||||
|
create_default_data
|
||||||
|
ct = create(:contract_template, name: "with signature legal text", project: Project.first)
|
||||||
|
ct.signature_legal_text = "legal text example"
|
||||||
|
ct.save
|
||||||
|
end
|
||||||
|
|
||||||
def response_body_json
|
def response_body_json
|
||||||
JSON.parse(response.body)
|
JSON.parse(response.body)
|
||||||
end
|
end
|
||||||
|
|||||||
@@ -203,6 +203,15 @@ RSpec.describe BroadcastsController, type: :controller do
|
|||||||
|
|
||||||
expect(BroadcastsChannel).to have_received(:broadcast_file_upload_updates)
|
expect(BroadcastsChannel).to have_received(:broadcast_file_upload_updates)
|
||||||
end
|
end
|
||||||
|
|
||||||
|
it "regenerates token if #update is called without broadcast param" do
|
||||||
|
old_token = broadcast.token
|
||||||
|
patch :update, params: { project_id: project.id, id: broadcast.id }
|
||||||
|
|
||||||
|
expect(response).to redirect_to [project, broadcast]
|
||||||
|
expect(flash.notice).to eq token_reset_notice
|
||||||
|
expect(Broadcast.last.token).not_to eq old_token
|
||||||
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
describe "#destroy" do
|
describe "#destroy" do
|
||||||
@@ -252,4 +261,8 @@ RSpec.describe BroadcastsController, type: :controller do
|
|||||||
def create_stream
|
def create_stream
|
||||||
t 'broadcasts.splash.actions.create_stream'
|
t 'broadcasts.splash.actions.create_stream'
|
||||||
end
|
end
|
||||||
|
|
||||||
|
def token_reset_notice
|
||||||
|
t 'broadcasts.update.reset_notice'
|
||||||
|
end
|
||||||
end
|
end
|
||||||
|
|||||||
@@ -7,6 +7,7 @@ FactoryBot.define do
|
|||||||
body "This is a test contract template."
|
body "This is a test contract template."
|
||||||
guardian_clause "Is the signer a minor?"
|
guardian_clause "Is the signer a minor?"
|
||||||
fee "$0.00"
|
fee "$0.00"
|
||||||
|
accessibility "public_template"
|
||||||
|
|
||||||
trait :archived do
|
trait :archived do
|
||||||
archived_at Time.zone.now
|
archived_at Time.zone.now
|
||||||
|
|||||||
@@ -49,12 +49,18 @@ FactoryBot.define do
|
|||||||
predefined_client_name "nat_geo"
|
predefined_client_name "nat_geo"
|
||||||
end
|
end
|
||||||
|
|
||||||
factory :project_with_contract_template do
|
factory :project_with_contract_template_public do
|
||||||
after(:build) do |project, _|
|
after(:build) do |project, _|
|
||||||
project.contract_templates << build(:contract_template, project: nil)
|
project.contract_templates << build(:contract_template, project: nil)
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
|
factory :project_with_contract_template_private do
|
||||||
|
after(:build) do |project, _|
|
||||||
|
project.contract_templates << build(:contract_template, project: nil, accessibility: "private_template")
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
factory :project_with_directories do
|
factory :project_with_directories do
|
||||||
after(:build) do |project, _|
|
after(:build) do |project, _|
|
||||||
project.directories << build(:directory, project: nil, name: "Shared")
|
project.directories << build(:directory, project: nil, name: "Shared")
|
||||||
|
|||||||
@@ -63,6 +63,21 @@ feature 'User managing broadcasts' do
|
|||||||
expect(page).to have_content(recording.download_file_name)
|
expect(page).to have_content(recording.download_file_name)
|
||||||
end
|
end
|
||||||
|
|
||||||
|
scenario 'Clicking Reset URL regenerates broadcast token' do
|
||||||
|
broadcast = create(:broadcast, :with_stream, :with_files, project: project)
|
||||||
|
old_token = broadcast.token
|
||||||
|
|
||||||
|
visit project_broadcast_path(project, broadcast)
|
||||||
|
|
||||||
|
expect(page).to have_content reset_url
|
||||||
|
expect(page).to have_xpath "//input[@readonly][@value='#{broadcast_url(old_token)}']"
|
||||||
|
|
||||||
|
click_link reset_url
|
||||||
|
expect(Broadcast.last.token).not_to eq old_token
|
||||||
|
expect(page).to have_xpath "//input[@readonly][@value='#{broadcast_url(Broadcast.last.token)}']"
|
||||||
|
expect(page).to have_content token_reset_notice
|
||||||
|
end
|
||||||
|
|
||||||
scenario 'user can go back and forth between live session and previous sessions', js: true do
|
scenario 'user can go back and forth between live session and previous sessions', js: true do
|
||||||
broadcast = create(:broadcast, :with_stream, :with_files, project: project)
|
broadcast = create(:broadcast, :with_stream, :with_files, project: project)
|
||||||
recording = create(:broadcast_recording, broadcast: broadcast)
|
recording = create(:broadcast_recording, broadcast: broadcast)
|
||||||
@@ -189,4 +204,12 @@ feature 'User managing broadcasts' do
|
|||||||
def create_stream
|
def create_stream
|
||||||
t 'broadcasts.splash.actions.create_stream'
|
t 'broadcasts.splash.actions.create_stream'
|
||||||
end
|
end
|
||||||
|
|
||||||
|
def reset_url
|
||||||
|
t 'broadcasts.show.actions.reset_url'
|
||||||
|
end
|
||||||
|
|
||||||
|
def token_reset_notice
|
||||||
|
t 'broadcasts.update.reset_notice'
|
||||||
|
end
|
||||||
end
|
end
|
||||||
|
|||||||
@@ -91,6 +91,21 @@ feature "User managing task requests" do
|
|||||||
expect(page).to have_content add_new_project_label
|
expect(page).to have_content add_new_project_label
|
||||||
end
|
end
|
||||||
|
|
||||||
|
scenario "user can click Chat Now and start chat event with a blank form" do
|
||||||
|
visit project_task_requests_path(project)
|
||||||
|
|
||||||
|
click_on create_task_request
|
||||||
|
|
||||||
|
expect(page).to have_content chat_now_button
|
||||||
|
expect(page).to have_content form_notice
|
||||||
|
|
||||||
|
expect do
|
||||||
|
click_on chat_now_button
|
||||||
|
end.to change(TaskRequest, :count).by(1)
|
||||||
|
|
||||||
|
expect(page).to have_content task_request_created_notice
|
||||||
|
end
|
||||||
|
|
||||||
private
|
private
|
||||||
|
|
||||||
def no_task_requests_label
|
def no_task_requests_label
|
||||||
@@ -120,4 +135,20 @@ feature "User managing task requests" do
|
|||||||
def schedule_demo
|
def schedule_demo
|
||||||
t 'task_requests.splash.actions.book_demo'
|
t 'task_requests.splash.actions.book_demo'
|
||||||
end
|
end
|
||||||
|
|
||||||
|
def create_task_request
|
||||||
|
t 'task_requests.index.actions.new'
|
||||||
|
end
|
||||||
|
|
||||||
|
def chat_now_button
|
||||||
|
t 'task_requests.form.actions.chat_now'
|
||||||
|
end
|
||||||
|
|
||||||
|
def form_notice
|
||||||
|
t 'task_requests.form.info_message'
|
||||||
|
end
|
||||||
|
|
||||||
|
def task_request_created_notice
|
||||||
|
t 'task_requests.create.success_message'
|
||||||
|
end
|
||||||
end
|
end
|
||||||
|
|||||||
@@ -35,6 +35,38 @@ describe GenerateContractsZipJob do
|
|||||||
expect(download.file).to be_attached
|
expect(download.file).to be_attached
|
||||||
end
|
end
|
||||||
|
|
||||||
|
it "generates ZIP containing CSV file with all releases data for all release types" do
|
||||||
|
release_types = %w[AcquiredMediaRelease AppearanceRelease LocationRelease MaterialRelease MedicalRelease MiscRelease MusicRelease TalentRelease]
|
||||||
|
create_releases_for_all_types
|
||||||
|
|
||||||
|
release_types.each do |type|
|
||||||
|
lowercase_plural = type.constantize.model_name.plural
|
||||||
|
GenerateContractsZipJob.perform_now(project, download, type, project.public_send(lowercase_plural).ids)
|
||||||
|
|
||||||
|
generated_zip = download.file.blob.download
|
||||||
|
csv_file_name = "#{project.name.parameterize}_#{lowercase_plural.gsub('_', '-')}.csv"
|
||||||
|
Zip::InputStream.open(StringIO.new(generated_zip)) do |io|
|
||||||
|
while entry = io.get_next_entry
|
||||||
|
next unless entry.name == csv_file_name
|
||||||
|
|
||||||
|
csv_file = entry.get_input_stream.read
|
||||||
|
|
||||||
|
release_class = Object.const_get type
|
||||||
|
release_headers = release_class.csv_headers
|
||||||
|
|
||||||
|
release_headers.each do |header|
|
||||||
|
expect(csv_file).to match header
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
dummy_zip_file_name = "#{project.name.parameterize}_#{lowercase_plural.gsub('_', '-')}.zip"
|
||||||
|
if File.exist?(file_fixture(dummy_zip_file_name))
|
||||||
|
File.delete(file_fixture(dummy_zip_file_name))
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
context "When there are errors" do
|
context "When there are errors" do
|
||||||
let(:error) { StandardError.new("Contracts or contract templates not found.") }
|
let(:error) { StandardError.new("Contracts or contract templates not found.") }
|
||||||
|
|
||||||
@@ -56,6 +88,21 @@ describe GenerateContractsZipJob do
|
|||||||
# Delete the file created in fixture.
|
# Delete the file created in fixture.
|
||||||
# Or the tests will fail on next run due to already existing files in existing zip.
|
# Or the tests will fail on next run due to already existing files in existing zip.
|
||||||
path = Rails.root.join("spec", "fixtures", "files")
|
path = Rails.root.join("spec", "fixtures", "files")
|
||||||
File.delete("#{path}/my-video-project_appearance-releases.zip") if File.exists? "#{path}/my-video-project_appearance-releases.zip"
|
if File.exists? "#{path}/my-video-project_appearance-releases.zip"
|
||||||
|
File.delete("#{path}/my-video-project_appearance-releases.zip")
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
private
|
||||||
|
|
||||||
|
def create_releases_for_all_types
|
||||||
|
create(:acquired_media_release_with_contract_template, :native, project: project)
|
||||||
|
create(:appearance_release_with_contract_template, :native, project: project, person_name: "John Doe")
|
||||||
|
create(:location_release_with_contract_template, :native, project: project)
|
||||||
|
create(:material_release_with_contract_template, :native, project: project)
|
||||||
|
create(:medical_release_with_contract_template, :native, project: project)
|
||||||
|
create(:misc_release_with_contract_template, :native, project: project)
|
||||||
|
create(:music_release_with_contract_template, project: project)
|
||||||
|
create(:talent_release_with_contract_template, :native, project: project)
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|||||||
@@ -36,7 +36,7 @@ RSpec.describe Project, type: :model do
|
|||||||
|
|
||||||
describe "#import_contract_templates" do
|
describe "#import_contract_templates" do
|
||||||
it "imports contract templates from other projects within the account" do
|
it "imports contract templates from other projects within the account" do
|
||||||
existing_project = create(:project_with_contract_template)
|
existing_project = create(:project_with_contract_template_public)
|
||||||
new_project = create(:project, name: "New Project", account: existing_project.account)
|
new_project = create(:project, name: "New Project", account: existing_project.account)
|
||||||
|
|
||||||
expect {
|
expect {
|
||||||
|
|||||||
@@ -13,8 +13,4 @@ RSpec.describe TaskRequest, type: :model do
|
|||||||
subject { described_class }
|
subject { described_class }
|
||||||
it { is_expected.to respond_to(:order_by_recent) }
|
it { is_expected.to respond_to(:order_by_recent) }
|
||||||
end
|
end
|
||||||
|
|
||||||
describe "#validations" do
|
|
||||||
it { should validate_numericality_of(:time_allowed).only_integer.is_greater_than_or_equal_to(2) }
|
|
||||||
end
|
|
||||||
end
|
end
|
||||||
|
|||||||
@@ -75,14 +75,17 @@ describe ContractTemplatePolicy do
|
|||||||
end
|
end
|
||||||
|
|
||||||
permissions ".scope" do
|
permissions ".scope" do
|
||||||
let!(:member_project) do
|
let!(:member_project_public_template) do
|
||||||
create(:project_with_contract_template, name: "Member Project", members: user, account: account)
|
create(:project_with_contract_template_public, name: "Member Project Public Template", members: user, account: account)
|
||||||
|
end
|
||||||
|
let!(:member_project_private_template) do
|
||||||
|
create(:project_with_contract_template_private, name: "Member Project Private Template", members: user, account: account)
|
||||||
end
|
end
|
||||||
let!(:non_member_project) do
|
let!(:non_member_project) do
|
||||||
create(:project_with_contract_template, name: "Non-Member Project", account: account)
|
create(:project_with_contract_template_public, name: "Non-Member Project", account: account)
|
||||||
end
|
end
|
||||||
let!(:outside_project) do
|
let!(:outside_project) do
|
||||||
create(:project_with_contract_template, name: "Outside Project", account: build(:account))
|
create(:project_with_contract_template_public, name: "Outside Project", account: build(:account))
|
||||||
end
|
end
|
||||||
|
|
||||||
let(:account) { build(:account) }
|
let(:account) { build(:account) }
|
||||||
@@ -93,7 +96,8 @@ describe ContractTemplatePolicy do
|
|||||||
context "for an account manager" do
|
context "for an account manager" do
|
||||||
let(:user) { create(:user, :account_manager, primary_account: account)}
|
let(:user) { create(:user, :account_manager, primary_account: account)}
|
||||||
|
|
||||||
it { is_expected.to include(member_project.contract_templates.first) }
|
it { is_expected.to include(member_project_public_template.contract_templates.first) }
|
||||||
|
it { is_expected.to include(member_project_private_template.contract_templates.first) }
|
||||||
it { is_expected.to include(non_member_project.contract_templates.first) }
|
it { is_expected.to include(non_member_project.contract_templates.first) }
|
||||||
it { is_expected.not_to include(outside_project.contract_templates.first) }
|
it { is_expected.not_to include(outside_project.contract_templates.first) }
|
||||||
end
|
end
|
||||||
@@ -101,7 +105,8 @@ describe ContractTemplatePolicy do
|
|||||||
context "for manager" do
|
context "for manager" do
|
||||||
let(:user) { create(:user, :manager, primary_account: account) }
|
let(:user) { create(:user, :manager, primary_account: account) }
|
||||||
|
|
||||||
it { is_expected.to include(member_project.contract_templates.first) }
|
it { is_expected.to include(member_project_public_template.contract_templates.first) }
|
||||||
|
it { is_expected.to include(member_project_private_template.contract_templates.first) }
|
||||||
it { is_expected.not_to include(non_member_project.contract_templates.first) }
|
it { is_expected.not_to include(non_member_project.contract_templates.first) }
|
||||||
it { is_expected.not_to include(outside_project.contract_templates.first) }
|
it { is_expected.not_to include(outside_project.contract_templates.first) }
|
||||||
end
|
end
|
||||||
@@ -109,7 +114,8 @@ describe ContractTemplatePolicy do
|
|||||||
context "for associate" do
|
context "for associate" do
|
||||||
let(:user) { create(:user, :associate, primary_account: account) }
|
let(:user) { create(:user, :associate, primary_account: account) }
|
||||||
|
|
||||||
it { is_expected.to include(member_project.contract_templates.first) }
|
it { is_expected.to include(member_project_public_template.contract_templates.first) }
|
||||||
|
it { is_expected.not_to include(member_project_private_template.contract_templates.first) }
|
||||||
it { is_expected.not_to include(non_member_project.contract_templates.first) }
|
it { is_expected.not_to include(non_member_project.contract_templates.first) }
|
||||||
it { is_expected.not_to include(outside_project.contract_templates.first) }
|
it { is_expected.not_to include(outside_project.contract_templates.first) }
|
||||||
end
|
end
|
||||||
|
|||||||
Reference in New Issue
Block a user