Compare commits

...

34 Commits

Author SHA1 Message Date
Senad Uka
eb7f8f1a43 Initial teams commit 2020-08-06 16:57:39 +00:00
Senad Uka
190ff2854b Upstream sync 2020-08-06 16:56:40 +00:00
Senad Uka
8214ba9e67 Changes 2020-08-03 21:52:04 +00:00
Senad Uka
9cbd8d31a8 Upstream sync 2020-07-29 05:15:02 +00:00
Senad Uka
9c3fac4ab9 Upstream sync 2020-07-27 10:17:56 +00:00
Senad Uka
8f13589c55 upstream sync 2020-07-22 19:14:34 +00:00
Senad Uka
cd0de9154c Upstream sync 2020-07-22 13:38:19 +00:00
Senad Uka
2590b6bdc9 Upstream sync 2020-07-21 13:12:27 +00:00
Senad Uka
40f241b75f Usptream sync 2020-07-20 13:28:40 +00:00
Senad Uka
add8304eab Master upstream sync 2020-07-16 18:02:45 +02:00
Senad Uka
f04d34d337 Upstream sync 2020-07-16 17:38:21 +02:00
Senad Uka
c033f5df17 Upstream sync 2020-07-16 17:27:57 +02:00
Senad Uka
7f49f31ebf Master sync 2020-07-15 11:58:34 +02:00
Senad Uka
4c49a5db03 Upstream sync 2020-07-14 14:10:30 +02:00
Senad Uka
35303cb570 Upstream sync 2020-07-09 11:06:17 +02:00
Senad Uka
1127f09263 Upstream sync 2020-07-08 18:27:49 +02:00
Senad Uka
19b1e75384 Upstream sync 2020-07-07 23:14:42 +02:00
Senad Uka
93a4ce462d Upstream sync 2020-07-07 21:45:30 +02:00
Senad Uka
0e16791d8b Upstream sync 2020-07-07 05:08:32 +02:00
Senad Uka
7cdb814d6d Upstream sync 2020-07-06 10:22:04 +02:00
Senad Uka
2dea0f29b9 Upstream sync 2020-07-03 10:23:03 +02:00
Senad Uka
d6a3542308 Upstream sync 2020-07-02 10:34:24 +02:00
Senad Uka
e49498bbbf Upstream sync 2020-07-01 06:39:02 +02:00
Senad Uka
dd0ac5b110 Upstream sync 2020-06-30 05:07:43 +02:00
Senad Uka
8951667e61 Upstrream sync 2020-06-26 18:45:11 +02:00
Senad Uka
fe131491cd Upstream sync 2020-06-26 04:55:50 +02:00
Senad Uka
290dbfa48b Upstream sync 2020-06-25 08:46:11 +02:00
Senad Uka
319cd89b29 Upstream sync 2020-06-24 04:48:12 +02:00
Senad Uka
6b0ea5b7df Upstream sync 2020-06-23 17:10:53 +02:00
Senad Uka
afee9d9bc9 Upstream sync 2020-06-22 20:28:22 +02:00
Senad Uka
072142811f Upstream sync 2020-06-22 14:14:25 +02:00
Senad Uka
b924b99762 Upstream sync 2020-06-19 09:23:07 +02:00
Senad Uka
988ef2beab Upstream sync 2020-06-18 17:51:08 +02:00
Senad Uka
1168bcdfdd Upstream sync 2020-06-18 16:56:11 +02:00
288 changed files with 10950 additions and 703 deletions

View File

@@ -16,9 +16,10 @@ REDIS_URL=
# Required for Zoom.us integration # Required for Zoom.us integration
ZOOM_API_KEY= ZOOM_API_KEY=
ZOOM_API_SECRET= ZOOM_API_SECRET=
ZOOM_ACCOUNT_NUMBER=
ZOOM_PRO_USERS_LIMIT= # defaults to 3 ZOOM_PRO_USERS_LIMIT= # defaults to 3
ZOOM_USER_TYPE= # 'pro' / 'basic' ZOOM_USER_TYPE= # 'pro' / 'basic'
ZOOM_ENABLE_RECORDINGS=0 # 0 / 1 ZOOM_ENABLE_RECORDINGS= # true / false (default: false)
# Token for webhooks authorization # Token for webhooks authorization
ZOOM_VERIFICATION_TOKEN= ZOOM_VERIFICATION_TOKEN=

10
Gemfile
View File

@@ -4,7 +4,7 @@ git_source(:github) { |repo| "https://github.com/#{repo}.git" }
ruby "2.6.3" ruby "2.6.3"
# Bundle edge Rails instead: gem "rails", github: "rails/rails" # Bundle edge Rails instead: gem "rails", github: "rails/rails"
gem "rails", "~> 6.0.0" gem "rails", "~> 6.0.3.1"
# Use postgresql as the database for Active Record # Use postgresql as the database for Active Record
gem "pg", "~> 0.18" gem "pg", "~> 0.18"
# Use Puma as the app server # Use Puma as the app server
@@ -30,9 +30,9 @@ gem "active_storage_base64", "~> 1.0.0"
gem "image_processing", "~> 1.2" gem "image_processing", "~> 1.2"
# Use Amazon Web Services S3 for file uploads in production # Use Amazon Web Services S3 for file uploads in production
gem "aws-sdk-s3", "~> 1.31.0", require: false, group: [:production, :review] gem "aws-sdk-s3", "~> 1.48", require: false, group: [:production, :review]
# Allow AWS API requests to be signed using IAM credentials # Allow AWS API requests to be signed using IAM credentials
gem "aws-sigv4", "~> 1.0.2" gem "aws-sigv4", "~> 1.1"
# Reduces boot times through caching; required in config/boot.rb # Reduces boot times through caching; required in config/boot.rb
gem "bootsnap", ">= 1.1.0", require: false gem "bootsnap", ">= 1.1.0", require: false
@@ -139,6 +139,10 @@ gem 'rack-cors'
# Ruby wrappers for the HubSpot REST API # Ruby wrappers for the HubSpot REST API
gem "hubspot-ruby" gem "hubspot-ruby"
# authenticate via Microsoft
# gem 'omniauth-microsoft_graph', git: 'https://github.com/m4c3/omniauth-microsoft_graph'
gem 'omniauth-microsoft_graph'
group :development, :test, :review do group :development, :test, :review do
# Call "byebug" anywhere in the code to stop execution and get a debugger console # Call "byebug" anywhere in the code to stop execution and get a debugger console
gem "byebug", "~> 11.0.1", platforms: [:mri, :mingw, :x64_mingw] gem "byebug", "~> 11.0.1", platforms: [:mri, :mingw, :x64_mingw]

View File

@@ -44,71 +44,71 @@ GEM
remote: https://rubygems.org/ remote: https://rubygems.org/
specs: specs:
Ascii85 (1.0.3) Ascii85 (1.0.3)
actioncable (6.0.0) actioncable (6.0.3.2)
actionpack (= 6.0.0) actionpack (= 6.0.3.2)
nio4r (~> 2.0) nio4r (~> 2.0)
websocket-driver (>= 0.6.1) websocket-driver (>= 0.6.1)
actionmailbox (6.0.0) actionmailbox (6.0.3.2)
actionpack (= 6.0.0) actionpack (= 6.0.3.2)
activejob (= 6.0.0) activejob (= 6.0.3.2)
activerecord (= 6.0.0) activerecord (= 6.0.3.2)
activestorage (= 6.0.0) activestorage (= 6.0.3.2)
activesupport (= 6.0.0) activesupport (= 6.0.3.2)
mail (>= 2.7.1) mail (>= 2.7.1)
actionmailer (6.0.0) actionmailer (6.0.3.2)
actionpack (= 6.0.0) actionpack (= 6.0.3.2)
actionview (= 6.0.0) actionview (= 6.0.3.2)
activejob (= 6.0.0) activejob (= 6.0.3.2)
mail (~> 2.5, >= 2.5.4) mail (~> 2.5, >= 2.5.4)
rails-dom-testing (~> 2.0) rails-dom-testing (~> 2.0)
actionpack (6.0.0) actionpack (6.0.3.2)
actionview (= 6.0.0) actionview (= 6.0.3.2)
activesupport (= 6.0.0) activesupport (= 6.0.3.2)
rack (~> 2.0) rack (~> 2.0, >= 2.0.8)
rack-test (>= 0.6.3) rack-test (>= 0.6.3)
rails-dom-testing (~> 2.0) rails-dom-testing (~> 2.0)
rails-html-sanitizer (~> 1.0, >= 1.2.0) rails-html-sanitizer (~> 1.0, >= 1.2.0)
actiontext (6.0.0) actiontext (6.0.3.2)
actionpack (= 6.0.0) actionpack (= 6.0.3.2)
activerecord (= 6.0.0) activerecord (= 6.0.3.2)
activestorage (= 6.0.0) activestorage (= 6.0.3.2)
activesupport (= 6.0.0) activesupport (= 6.0.3.2)
nokogiri (>= 1.8.5) nokogiri (>= 1.8.5)
actionview (6.0.0) actionview (6.0.3.2)
activesupport (= 6.0.0) activesupport (= 6.0.3.2)
builder (~> 3.1) builder (~> 3.1)
erubi (~> 1.4) erubi (~> 1.4)
rails-dom-testing (~> 2.0) rails-dom-testing (~> 2.0)
rails-html-sanitizer (~> 1.1, >= 1.2.0) rails-html-sanitizer (~> 1.1, >= 1.2.0)
active_storage_base64 (1.0.0) active_storage_base64 (1.0.0)
rails (~> 6.0) rails (~> 6.0)
activejob (6.0.0) activejob (6.0.3.2)
activesupport (= 6.0.0) activesupport (= 6.0.3.2)
globalid (>= 0.3.6) globalid (>= 0.3.6)
activemodel (6.0.0) activemodel (6.0.3.2)
activesupport (= 6.0.0) activesupport (= 6.0.3.2)
activemodel-serializers-xml (1.0.2) activemodel-serializers-xml (1.0.2)
activemodel (> 5.x) activemodel (> 5.x)
activesupport (> 5.x) activesupport (> 5.x)
builder (~> 3.1) builder (~> 3.1)
activerecord (6.0.0) activerecord (6.0.3.2)
activemodel (= 6.0.0) activemodel (= 6.0.3.2)
activesupport (= 6.0.0) activesupport (= 6.0.3.2)
activeresource (5.1.0) activeresource (5.1.0)
activemodel (>= 5.0, < 7) activemodel (>= 5.0, < 7)
activemodel-serializers-xml (~> 1.0) activemodel-serializers-xml (~> 1.0)
activesupport (>= 5.0, < 7) activesupport (>= 5.0, < 7)
activestorage (6.0.0) activestorage (6.0.3.2)
actionpack (= 6.0.0) actionpack (= 6.0.3.2)
activejob (= 6.0.0) activejob (= 6.0.3.2)
activerecord (= 6.0.0) activerecord (= 6.0.3.2)
marcel (~> 0.3.1) marcel (~> 0.3.1)
activesupport (6.0.0) activesupport (6.0.3.2)
concurrent-ruby (~> 1.0, >= 1.0.2) concurrent-ruby (~> 1.0, >= 1.0.2)
i18n (>= 0.7, < 2) i18n (>= 0.7, < 2)
minitest (~> 5.1) minitest (~> 5.1)
tzinfo (~> 1.1) tzinfo (~> 1.1)
zeitwerk (~> 2.1, >= 2.1.8) zeitwerk (~> 2.2, >= 2.2.2)
addressable (2.7.0) addressable (2.7.0)
public_suffix (>= 2.0.2, < 5.0) public_suffix (>= 2.0.2, < 5.0)
afm (0.2.2) afm (0.2.2)
@@ -117,21 +117,22 @@ GEM
ast (2.4.0) ast (2.4.0)
autoprefixer-rails (9.7.3) autoprefixer-rails (9.7.3)
execjs execjs
aws-eventstream (1.0.3) aws-eventstream (1.1.0)
aws-partitions (1.210.0) aws-partitions (1.337.0)
aws-sdk-core (3.46.2) aws-sdk-core (3.102.1)
aws-eventstream (~> 1.0) aws-eventstream (~> 1, >= 1.0.2)
aws-partitions (~> 1.0) aws-partitions (~> 1, >= 1.239.0)
aws-sigv4 (~> 1.0) aws-sigv4 (~> 1.1)
jmespath (~> 1.0) jmespath (~> 1.0)
aws-sdk-kms (1.13.0) aws-sdk-kms (1.35.0)
aws-sdk-core (~> 3, >= 3.39.0) aws-sdk-core (~> 3, >= 3.99.0)
aws-sigv4 (~> 1.0) aws-sigv4 (~> 1.1)
aws-sdk-s3 (1.31.0) aws-sdk-s3 (1.72.0)
aws-sdk-core (~> 3, >= 3.39.0) aws-sdk-core (~> 3, >= 3.102.1)
aws-sdk-kms (~> 1) aws-sdk-kms (~> 1)
aws-sigv4 (~> 1.0) aws-sigv4 (~> 1.1)
aws-sigv4 (1.0.3) aws-sigv4 (1.2.1)
aws-eventstream (~> 1, >= 1.0.2)
axlsx (3.0.0.pre) axlsx (3.0.0.pre)
htmlentities (~> 4.3, >= 4.3.4) htmlentities (~> 4.3, >= 4.3.4)
mimemagic (~> 0.3) mimemagic (~> 0.3)
@@ -181,7 +182,7 @@ GEM
coffee-script-source coffee-script-source
execjs execjs
coffee-script-source (1.12.2) coffee-script-source (1.12.2)
concurrent-ruby (1.1.5) concurrent-ruby (1.1.6)
connection_pool (2.2.2) connection_pool (2.2.2)
countries (2.1.4) countries (2.1.4)
i18n_data (~> 0.8.0) i18n_data (~> 0.8.0)
@@ -219,6 +220,7 @@ GEM
activesupport (>= 4.2.0) activesupport (>= 4.2.0)
hashdiff (1.0.1) hashdiff (1.0.1)
hashery (2.1.2) hashery (2.1.2)
hashie (4.1.0)
hexapdf (0.9.3) hexapdf (0.9.3)
cmdparse (~> 3.0, >= 3.0.3) cmdparse (~> 3.0, >= 3.0.3)
geom2d (~> 0.2) geom2d (~> 0.2)
@@ -230,7 +232,7 @@ GEM
hubspot-ruby (0.9.0) hubspot-ruby (0.9.0)
activesupport (>= 3.0.0) activesupport (>= 3.0.0)
httparty (>= 0.10.0) httparty (>= 0.10.0)
i18n (1.8.2) i18n (1.8.3)
concurrent-ruby (~> 1.0) concurrent-ruby (~> 1.0)
i18n_data (0.8.0) i18n_data (0.8.0)
i18n_yaml_sorter (0.2.0) i18n_yaml_sorter (0.2.0)
@@ -270,22 +272,22 @@ GEM
ruby_dep (~> 1.2) ruby_dep (~> 1.2)
loaf (0.8.1) loaf (0.8.1)
rails (>= 3.2) rails (>= 3.2)
loofah (2.4.0) loofah (2.6.0)
crass (~> 1.0.2) crass (~> 1.0.2)
nokogiri (>= 1.5.9) nokogiri (>= 1.5.9)
mail (2.7.1) mail (2.7.1)
mini_mime (>= 0.1.1) mini_mime (>= 0.1.1)
marcel (0.3.3) marcel (0.3.3)
mimemagic (~> 0.3.2) mimemagic (~> 0.3.2)
method_source (0.9.2) method_source (1.0.0)
mime-types (3.3) mime-types (3.3)
mime-types-data (~> 3.2015) mime-types-data (~> 3.2015)
mime-types-data (3.2019.0904) mime-types-data (3.2019.0904)
mimemagic (0.3.3) mimemagic (0.3.5)
mini_magick (4.9.5) mini_magick (4.9.5)
mini_mime (1.0.2) mini_mime (1.0.2)
mini_portile2 (2.4.0) mini_portile2 (2.4.0)
minitest (5.14.0) minitest (5.14.1)
monetize (1.9.2) monetize (1.9.2)
money (~> 6.12) money (~> 6.12)
money (6.13.4) money (6.13.4)
@@ -296,10 +298,11 @@ GEM
money (~> 6.13.2) money (~> 6.13.2)
railties (>= 3.0) railties (>= 3.0)
msgpack (1.3.1) msgpack (1.3.1)
multi_json (1.15.0)
multi_xml (0.6.0) multi_xml (0.6.0)
multipart-post (2.1.1) multipart-post (2.1.1)
nio4r (2.5.1) nio4r (2.5.2)
nokogiri (1.10.7) nokogiri (1.10.9)
mini_portile2 (~> 2.4.0) mini_portile2 (~> 2.4.0)
oath (1.1.0) oath (1.1.0)
bcrypt bcrypt
@@ -307,6 +310,21 @@ GEM
warden warden
oath-generators (1.0.1) oath-generators (1.0.1)
oath (>= 0.0.12) oath (>= 0.0.12)
oauth2 (1.4.4)
faraday (>= 0.8, < 2.0)
jwt (>= 1.0, < 3.0)
multi_json (~> 1.3)
multi_xml (~> 0.5)
rack (>= 1.2, < 3)
omniauth (1.9.1)
hashie (>= 3.4.6)
rack (>= 1.6.2, < 3)
omniauth-microsoft_graph (0.3.3)
omniauth (~> 1.1, >= 1.1.1)
omniauth-oauth2 (~> 1.6)
omniauth-oauth2 (1.6.0)
oauth2 (~> 1.1)
omniauth (~> 1.9)
parallel (1.19.1) parallel (1.19.1)
parity (3.2.0) parity (3.2.0)
parser (2.6.5.0) parser (2.6.5.0)
@@ -337,20 +355,20 @@ GEM
rack rack
rack-test (1.1.0) rack-test (1.1.0)
rack (>= 1.0, < 3) rack (>= 1.0, < 3)
rails (6.0.0) rails (6.0.3.2)
actioncable (= 6.0.0) actioncable (= 6.0.3.2)
actionmailbox (= 6.0.0) actionmailbox (= 6.0.3.2)
actionmailer (= 6.0.0) actionmailer (= 6.0.3.2)
actionpack (= 6.0.0) actionpack (= 6.0.3.2)
actiontext (= 6.0.0) actiontext (= 6.0.3.2)
actionview (= 6.0.0) actionview (= 6.0.3.2)
activejob (= 6.0.0) activejob (= 6.0.3.2)
activemodel (= 6.0.0) activemodel (= 6.0.3.2)
activerecord (= 6.0.0) activerecord (= 6.0.3.2)
activestorage (= 6.0.0) activestorage (= 6.0.3.2)
activesupport (= 6.0.0) activesupport (= 6.0.3.2)
bundler (>= 1.3.0) bundler (>= 1.3.0)
railties (= 6.0.0) railties (= 6.0.3.2)
sprockets-rails (>= 2.0.0) sprockets-rails (>= 2.0.0)
rails-controller-testing (1.0.4) rails-controller-testing (1.0.4)
actionpack (>= 5.0.1.x) actionpack (>= 5.0.1.x)
@@ -363,9 +381,9 @@ GEM
nokogiri (>= 1.6) nokogiri (>= 1.6)
rails-html-sanitizer (1.3.0) rails-html-sanitizer (1.3.0)
loofah (~> 2.3) loofah (~> 2.3)
railties (6.0.0) railties (6.0.3.2)
actionpack (= 6.0.0) actionpack (= 6.0.3.2)
activesupport (= 6.0.0) activesupport (= 6.0.3.2)
method_source method_source
rake (>= 0.8.7) rake (>= 0.8.7)
thor (>= 0.20.3, < 2.0) thor (>= 0.20.3, < 2.0)
@@ -469,7 +487,7 @@ GEM
turbolinks-source (5.2.0) turbolinks-source (5.2.0)
typhoeus (1.3.1) typhoeus (1.3.1)
ethon (>= 0.9.0) ethon (>= 0.9.0)
tzinfo (1.2.6) tzinfo (1.2.7)
thread_safe (~> 0.1) thread_safe (~> 0.1)
uglifier (4.1.20) uglifier (4.1.20)
execjs (>= 0.3.0, < 3) execjs (>= 0.3.0, < 3)
@@ -494,9 +512,9 @@ GEM
activesupport (>= 4.2) activesupport (>= 4.2)
rack-proxy (>= 0.6.1) rack-proxy (>= 0.6.1)
railties (>= 4.2) railties (>= 4.2)
websocket-driver (0.7.1) websocket-driver (0.7.2)
websocket-extensions (>= 0.1.0) websocket-extensions (>= 0.1.0)
websocket-extensions (0.1.4) websocket-extensions (0.1.5)
will_paginate (3.2.1) will_paginate (3.2.1)
will_paginate-bootstrap4 (0.2.2) will_paginate-bootstrap4 (0.2.2)
will_paginate (~> 3.0, >= 3.0.0) will_paginate (~> 3.0, >= 3.0.0)
@@ -504,7 +522,7 @@ GEM
wkhtmltopdf-heroku (2.12.5.0) wkhtmltopdf-heroku (2.12.5.0)
xpath (3.2.0) xpath (3.2.0)
nokogiri (~> 1.8) nokogiri (~> 1.8)
zeitwerk (2.2.2) zeitwerk (2.3.1)
PLATFORMS PLATFORMS
ruby ruby
@@ -514,8 +532,8 @@ DEPENDENCIES
activeresource (= 5.1.0) activeresource (= 5.1.0)
acts-as-taggable-on! acts-as-taggable-on!
analytics-ruby analytics-ruby
aws-sdk-s3 (~> 1.31.0) aws-sdk-s3 (~> 1.48)
aws-sigv4 (~> 1.0.2) aws-sigv4 (~> 1.1)
axlsx (~> 3.0.0.pre) axlsx (~> 3.0.0.pre)
axlsx_rails (~> 0.5.2) axlsx_rails (~> 0.5.2)
axlsx_styler (~> 0.2.0) axlsx_styler (~> 0.2.0)
@@ -551,6 +569,7 @@ DEPENDENCIES
mux_ruby! mux_ruby!
oath (~> 1.1.0) oath (~> 1.1.0)
oath-generators (~> 1.0.1) oath-generators (~> 1.0.1)
omniauth-microsoft_graph
parity (~> 3.2.0) parity (~> 3.2.0)
pdf-reader (~> 2.1.0) pdf-reader (~> 2.1.0)
pdfkit (~> 0.8.2) pdfkit (~> 0.8.2)
@@ -561,7 +580,7 @@ DEPENDENCIES
rack! rack!
rack-contrib (~> 2.0.1) rack-contrib (~> 2.0.1)
rack-cors rack-cors
rails (~> 6.0.0) rails (~> 6.0.3.1)
rails-controller-testing (~> 1.0.4) rails-controller-testing (~> 1.0.4)
rails-data-migrations (~> 1.2.0) rails-data-migrations (~> 1.2.0)
redcarpet (~> 3.4.0) redcarpet (~> 3.4.0)

View File

@@ -21,11 +21,13 @@ $(document).on "turbolinks:load", ->
refreshBroadcastVideo: (data) -> refreshBroadcastVideo: (data) ->
$("#broadcast_updates").html data.status_content $("#broadcast_updates").html data.status_content
if data.streamer_status == 'recording' && data.status == 'active' stream_selected = $("#broadcast_video").data('videoType') == 'stream';
if data.streamer_status == 'recording' && data.status == 'active' && stream_selected
$("#broadcast_video").html data.video_content $("#broadcast_video").html data.video_content
new (Clappr.Player)( new (Clappr.Player)(
<%= "baseUrl: 'http://cdn.clappr.io/latest'," if Rails.env.test? %>
parentId: '#broadcast_video' parentId: '#broadcast_video'
source: data.playback_url source: data.full_live_stream_playback_url
width: '100%', width: '100%',
height: '100%', height: '100%',
mute: true, mute: true,

View File

@@ -0,0 +1,50 @@
$(document).on("click", "[data-behavior=select_contract_template]", function() {
var _this = this;
var checkbox = $(this).children("input:checkbox");
selectContractTemplate(_this, checkbox);
});
$(document).on("click", "[data-behavior=select_contract_template] input[type='checkbox']", function(e) {
e.stopPropagation();
var _this = this;
var checkbox = $(this);
selectContractTemplate(_this, checkbox);
});
function selectContractTemplate(clicked_element, checkbox) {
if (clicked_element.hasChildNodes()) {
if(checkbox.prop("checked")) {
checkbox.prop('checked', false);
} else {
checkbox.prop('checked', true);
}
}
var checked = checkbox.prop("checked");
var project_id = JSON.parse($('#group_qr_code').attr('data-project-id'));
var contract_template_ids = JSON.parse($('#group_qr_code').attr('data-contract-template-ids'));
var selected_contract_template_id = checkbox.val();
if (checked && !contract_template_ids.includes(selected_contract_template_id)) {
contract_template_ids.push(selected_contract_template_id);
} else if(!checked && contract_template_ids.includes(selected_contract_template_id)) {
contract_template_ids.splice( $.inArray(selected_contract_template_id, contract_template_ids), 1 );
}
$('#group_qr_code').attr('data-contract-template-ids', JSON.stringify(contract_template_ids));
if (contract_template_ids.length >= 2) {
multi_sign_ids = $.param({multi_sign_ids: contract_template_ids});
contract_template_url = "/en/contract_templates/" + contract_template_ids[0] + "/qr_codes?" + multi_sign_ids
$("#group_qr_code").attr("href", contract_template_url);
$("#group_qr_code").attr("target", "_blank");
$("#group_qr_code").removeClass('disabled');
} else if (contract_template_ids.length < 2) {
$("#group_qr_code").attr("href", "javascript:void(0);");
$("#group_qr_code").addClass('disabled');
}
}

View File

@@ -51,10 +51,8 @@ $(document).on("turbolinks:load", function() {
$("[data-behavior=guardian-photo-preview]").each(function(index, element) { $("[data-behavior=guardian-photo-preview]").each(function(index, element) {
App.PhotoPreview.init(element); App.PhotoPreview.init(element);
}); });
$("[data-behavior=take-person-photo]").click(function(e) { $("[data-behavior=trigger-click]").click(function(e) {
$("[data-ujs-target=person-photo-input]").trigger("click"); const target = $(this).data("target");
}); $(target).trigger("click");
$("[data-behavior=take-guardian-photo]").click(function(e) {
$("[data-ujs-target=guardian-photo-input]").trigger("click");
}); });
}); });

View File

@@ -1,24 +0,0 @@
$(document).on("click", "[data-behavior=play_recording]", function() {
if ($(this).hasClass('active')){
return false;
}
var playback_url = $(this).attr("data-playback-url")
$("#broadcast_video").empty();
new Clappr.Player({
parentId: '#broadcast_video',
source: playback_url,
width: '100%',
height: '100%',
autoPlay: true
});
$(".dropdown-menu").children().removeClass('active');
$(".dropdown-menu").children().children('i').remove();
$(this).siblings().removeClass('active');
$(this).siblings().children("i").remove();
$(this).addClass('active');
$(this).prepend('<i class="fa fa-check">&nbsp;</i>');
});

View File

@@ -0,0 +1,28 @@
$(document).on("click", "[data-behavior=play_recording]", function() {
if ($(this).hasClass('active')){
return false;
}
$("#broadcast_video").data('videoType', 'recording');
var playback_url = $(this).attr("data-playback-url")
$("#broadcast_video").empty();
new Clappr.Player({
<%= "baseUrl: 'http://cdn.clappr.io/latest'," if Rails.env.test? %>
parentId: '#broadcast_video',
source: playback_url,
width: '100%',
height: '100%',
autoPlay: true
});
$(".dropdown-menu").children().removeClass('active');
$(".dropdown-menu").children().children('i').remove();
$(this).siblings().removeClass('active');
$(this).siblings().children("i").remove();
$(this).addClass('active');
$(this).prepend('<i class="fa fa-check">&nbsp;</i>');
});
$(document).on("click", "[data-behavior=play_stream]", function() { $("#broadcast_video").data('videoType', 'stream'); });

View File

@@ -0,0 +1,13 @@
$(document).on("turbolinks:load", function() {
$("[data-behavior=update-required-status]").click(function(e) {
const required = !!($(this)[0] && $(this)[0].checked);
$("[data-required-tag=guardian]").each(function(index, element) {
const labelForField = element.previousSibling;
element.required = required;
labelForField.classList.add("required");
});
});
});

View File

@@ -14,6 +14,7 @@ $red: #F9002B;
$green: #51B61B; $green: #51B61B;
$teal: #32C498; $teal: #32C498;
$purple: #5139EE; $purple: #5139EE;
$yellow: #F9BE1B;
$dark: $gray-900; $dark: $gray-900;
$success: $teal; $success: $teal;
$link-color: $body-color; $link-color: $body-color;

View File

@@ -37,14 +37,14 @@ label {
&.release-me { &.release-me {
span:last-child { span:last-child {
background-color: $teal; background-color: $teal;
color: $body-color; color: $white;
} }
} }
&.direct-me { &.direct-me {
span:last-child { span:last-child {
background-color: $green; background-color: $green;
color: $body-color; color: $white;
} }
} }
@@ -58,7 +58,14 @@ label {
&.deliver-me { &.deliver-me {
span:last-child { span:last-child {
background-color: $purple; background-color: $purple;
color: white; color: $white;
}
}
&.task-me {
span:last-child {
background-color: $yellow;
color: $white;
} }
} }

View File

@@ -16,6 +16,7 @@ class BroadcastsChannel < ApplicationCable::Channel
event: :broadcast_stream_update, event: :broadcast_stream_update,
status: broadcast.status, status: broadcast.status,
playback_url: broadcast.stream_playback_url, playback_url: broadcast.stream_playback_url,
full_live_stream_playback_url: broadcast.full_live_stream_playback_url,
video_content: video_content, video_content: video_content,
status_content: status_content, status_content: status_content,
streamer_status: broadcast.streamer_status streamer_status: broadcast.streamer_status

View File

@@ -17,7 +17,7 @@ class AccountsController < ApplicationController
if sign_in(user) if sign_in(user)
TrackAnalyticsJob.perform_later(user, user.primary_account, :track_guest_sign_up, user_agent: request.user_agent, user_ip: request.remote_ip) TrackAnalyticsJob.perform_later(user, user.primary_account, :track_guest_sign_up, user_agent: request.user_agent, user_ip: request.remote_ip)
SubmitHubspotFormJob.perform_later(user.email, account.name, i_m_interested_in: user.interested_product_name) SubmitHubspotFormJob.perform_later(user.first_name, user.last_name, user.email, account.name, i_m_interested_in: user.interested_product_name)
redirect_to signed_in_root_path redirect_to signed_in_root_path
else else
redirect_to new_session_path, alert: t(".notice") redirect_to new_session_path, alert: t(".notice")

View File

@@ -56,35 +56,74 @@ class AcquiredMediaReleasesController < ApplicationController
end end
end end
def person_params
%i[
person_first_name
person_last_name
person_phone
person_company
person_email
person_title
person_address_street1
person_address_street2
person_address_city
person_address_state
person_address_zip
person_address_country
]
end
def guardian_params
%i[
guardian_first_name
guardian_last_name
guardian_phone
guardian_email
guardian_photo
guardian_address_street1
guardian_address_street2
guardian_address_city
guardian_address_state
guardian_address_zip
guardian_address_country
]
end
def second_guardian_params
%i[
guardian_2_first_name
guardian_2_last_name
guardian_2_phone
guardian_2_email
guardian_2_photo
guardian_2_address_street1
guardian_2_address_street2
guardian_2_address_city
guardian_2_address_state
guardian_2_address_zip
guardian_2_address_country
]
end
def acquired_media_release_params def acquired_media_release_params
params.require(:acquired_media_release).permit( params.require(:acquired_media_release).permit(person_params,
:name, guardian_params,
:territory, second_guardian_params,
:term, :minor,
:person_first_name, :name,
:person_last_name, :territory,
:person_phone, :term,
:person_email, :contract,
:person_company, :applicable_medium_id, :applicable_medium_text,
:person_title, :territory_id, :territory_text,
:person_address_street1, :term_id, :term_text,
:person_address_street2, :restriction_id, :restriction_text,
:person_address_city, categories: [],
:person_address_state, file_infos_attributes: %i[
:person_address_zip, filename
:person_address_country, content_type
:contract, byte_size
:applicable_medium_id, :applicable_medium_text, ])
:territory_id, :territory_text,
:term_id, :term_text,
:restriction_id, :restriction_text,
categories: [],
file_infos_attributes: [
:filename,
:content_type,
:byte_size
]
)
end end
def build_acquired_media_release(attrs = {}) def build_acquired_media_release(attrs = {})

View File

@@ -0,0 +1,36 @@
class Admin::TaskRequestsController < Admin::ApplicationController
before_action :set_task_request, only: [:edit, :update, :show]
def index
@task_requests = task_requests.order_by_recent.paginate(page: params[:page])
end
def edit
end
def show
@files = @task_request.files.paginate(page: params[:page])
end
def update
if @task_request.update(task_request_params)
redirect_to [:admin, :task_requests], notice: t(".notice")
else
render :edit
end
end
private
def task_request_params
params.require(:task_request).permit(:status, :deliverable_url)
end
def task_requests
policy_scope TaskRequest
end
def set_task_request
@task_request = authorize policy_scope(TaskRequest).find(params[:id])
end
end

View File

@@ -17,7 +17,9 @@ class Api::ApiController < ActionController::Base
def return_error(exception) def return_error(exception)
raise exception if Rails.env.test? raise exception if Rails.env.test?
logger.error "==Handled=======" Raven.capture_exception(exception)
logger.error "==Handled======"
logger.error exception.message logger.error exception.message
logger.error exception.backtrace.join("\n") logger.error exception.backtrace.join("\n")
logger.error "==Handled=======" logger.error "==Handled======="

View File

@@ -19,5 +19,11 @@ class Api::AppearanceReleasesController < Api::ReleasesController
guardian_photo[:io] = StringIO.new(Base64.decode64(guardian_photo[:io])) guardian_photo[:io] = StringIO.new(Base64.decode64(guardian_photo[:io]))
release.guardian_photo.attach(io: guardian_photo[:io], filename: guardian_photo[:filename]) release.guardian_photo.attach(io: guardian_photo[:io], filename: guardian_photo[:filename])
end end
guardian_2_photo = release_create_params[:guardian_2_photo]
if guardian_2_photo
guardian_2_photo[:io] = StringIO.new(Base64.decode64(guardian_2_photo[:io]))
release.guardian_2_photo.attach(io: guardian_2_photo[:io], filename: guardian_2_photo[:filename])
end
end end
end end

View File

@@ -24,8 +24,12 @@ class Api::BroadcastsController < Api::ApiController
def update def update
file_params.each do |file| file_params.each do |file|
file[:io] = StringIO.new(Base64.decode64(file[:io])) if file.is_a?(String)
@broadcast.files.attach(io: file[:io], filename: file[:filename]) @broadcast.files.attach(file)
else
file[:io] = StringIO.new(Base64.decode64(file[:io]))
@broadcast.files.attach(file.to_h.symbolize_keys)
end
end end
@broadcast.save! @broadcast.save!

View File

@@ -0,0 +1,11 @@
class Api::MedicalReleasesController < Api::ReleasesController
deserializable_resource :medical_release, only: [:create, :update]
def model_name
"medical_release"
end
def attributes_for_index
[:name]
end
end

View File

@@ -0,0 +1,11 @@
class Api::MiscReleasesController < Api::ReleasesController
deserializable_resource :misc_release, only: [:create, :update]
def model_name
"misc_release"
end
def attributes_for_index
[:name]
end
end

View File

@@ -103,10 +103,16 @@ class Api::ReleasesController < Api::ApiController
if ["appearance_release", "talent_release"].include?(name) if ["appearance_release", "talent_release"].include?(name)
has_many :guardian_photos do has_many :guardian_photos do
data do data do
[@object.guardian_photo.try(:attachment)].compact [
@object.guardian_photo.try(:attachment),
@object.guardian_2_photo.try(:attachment)
].compact
end end
meta do meta do
{ count: @object.try(:guardian_photo).try(:attached?) ? 1 : 0 } { count:
(@object.try(:guardian_photo).try(:attached?) ? 1 : 0) +
(@object.try(:guardian_2_photo).try(:attached?) ? 1 : 0)
}
end end
end end
end end
@@ -170,7 +176,7 @@ class Api::ReleasesController < Api::ApiController
def release_create_params def release_create_params
parameters = params.require(model_name).permit! parameters = params.require(model_name).permit!
keys = model_constant.new.attributes.keys + [:guardian_photo, :person_photo, :photos, :signature, :signature_base64, :file_infos_attributes] keys = model_constant.new.attributes.keys + [:guardian_photo, :guardian_2_photo, :person_photo, :photos, :signature, :signature_base64, :file_infos_attributes]
parameters[:signature_base64] = parameters[:signature] parameters[:signature_base64] = parameters[:signature]
parameters = parameters.slice(*keys).except(:created_at, :updated_at, :id, :user_id, :signature) parameters = parameters.slice(*keys).except(:created_at, :updated_at, :id, :user_id, :signature)
parameters parameters

View File

@@ -10,8 +10,10 @@ class Api::SyncController < Api::ApiController
@appearance_releases = (AppearanceRelease.where(project: accessible_projects)) @appearance_releases = (AppearanceRelease.where(project: accessible_projects))
@location_releases = (LocationRelease.where(project: accessible_projects)) @location_releases = (LocationRelease.where(project: accessible_projects))
@material_releases = (MaterialRelease.where(project: accessible_projects)) @material_releases = (MaterialRelease.where(project: accessible_projects))
@medical_releases = MedicalRelease.where(project: accessible_projects)
@misc_releases = MiscRelease.where(project: accessible_projects)
@talent_releases = (TalentRelease.where(project: accessible_projects)) @talent_releases = (TalentRelease.where(project: accessible_projects))
@notes = notes_query(Note.where(notable: @appearance_releases + @location_releases + @material_releases + @talent_releases + @acquired_media_releases )) @notes = notes_query(Note.where(notable: @appearance_releases + @location_releases + @material_releases + @medical_releases + @misc_releases + @talent_releases + @acquired_media_releases ))
render json: { render json: {
data: { data: {
@@ -22,6 +24,8 @@ class Api::SyncController < Api::ApiController
appearance_releases: releases_query(@appearance_releases), appearance_releases: releases_query(@appearance_releases),
location_releases: releases_query(@location_releases), location_releases: releases_query(@location_releases),
material_releases: releases_query(@material_releases), material_releases: releases_query(@material_releases),
medical_releases: releases_query(@medical_releases),
misc_releases: releases_query(@misc_releases),
talent_releases: releases_query(@talent_releases), talent_releases: releases_query(@talent_releases),
notes: @notes notes: @notes
} }

View File

@@ -17,5 +17,11 @@ class Api::TalentReleasesController < Api::ReleasesController
guardian_photo[:io] = StringIO.new(Base64.decode64(guardian_photo[:io])) guardian_photo[:io] = StringIO.new(Base64.decode64(guardian_photo[:io]))
release.guardian_photo.attach(io: guardian_photo[:io], filename: guardian_photo[:filename]) release.guardian_photo.attach(io: guardian_photo[:io], filename: guardian_photo[:filename])
end end
guardian_2_photo = release_create_params[:guardian_2_photo]
if guardian_2_photo
guardian_2_photo[:io] = StringIO.new(Base64.decode64(guardian_2_photo[:io]))
release.guardian_2_photo.attach(io: guardian_2_photo[:io], filename: guardian_2_photo[:filename])
end
end end
end end

View File

@@ -5,6 +5,8 @@ class Api::UserTokenController < Knock::AuthTokenController
# Catch exception and return JSON-formatted error # Catch exception and return JSON-formatted error
def return_error(exception) def return_error(exception)
Raven.capture_exception(exception)
logger.error "==Handled=======" logger.error "==Handled======="
logger.error exception.message logger.error exception.message
logger.error exception.backtrace.join("\n") logger.error exception.backtrace.join("\n")

View File

@@ -77,9 +77,43 @@ class AppearanceReleasesController < ApplicationController
results results
end end
def person_params
%i[
person_first_name
person_last_name
person_phone
person_email
person_photo
person_address_street1
]
end
def guardian_params
%i[
guardian_first_name
guardian_last_name
guardian_phone
guardian_email
guardian_photo
guardian_address_street1
]
end
def second_guardian_params
%i[
guardian_2_first_name
guardian_2_last_name
guardian_2_phone
guardian_2_email
guardian_2_photo
guardian_2_address_street1
]
end
def appearance_release_params def appearance_release_params
params.require(:appearance_release).permit(:contract, :guardian_address, :guardian_first_name, :guardian_last_name, :guardian_phone, :guardian_photo, :guardian_email, :minor, params.require(:appearance_release).permit(person_params,
:person_address, :person_first_name, :person_last_name, :person_phone, :person_email, :person_photo, guardian_params, second_guardian_params,
:contract, :minor,
:applicable_medium_id, :applicable_medium_text, :applicable_medium_id, :applicable_medium_text,
:territory_id, :territory_text, :territory_id, :territory_text,
:term_id, :term_text, :person_date_of_birth, :term_id, :term_text, :person_date_of_birth,

View File

@@ -0,0 +1,28 @@
class ApprovalsController < ApplicationController
before_action :set_releasable
before_action :set_project
layout "project"
def create
@releasable.approve_by(current_user)
if @releasable.save
redirect_to [@project, "#{@releasable_param.name.pluralize}"], notice: t('.release_approved', release_type: @releasable.model_name.human)
end
end
private
def releasable_param
@releasable_param ||= ReleasableParam.new(params.to_unsafe_h)
end
def set_releasable
@releasable = authorize policy_scope(releasable_param.type).find(releasable_param.id)
end
def set_project
@project = @releasable.project
end
end

View File

@@ -3,8 +3,9 @@ class BroadcastsController < ApplicationController
before_action :set_project before_action :set_project
before_action :build_broadcast, only: [:new, :create] 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 :set_multi_view_broadcasts, only: [:show]
before_action :show_splash_screen, only: :index
def index def index
@broadcasts = filtered_broadcasts.order_by_recent.paginate(page: params[:page]) @broadcasts = filtered_broadcasts.order_by_recent.paginate(page: params[:page])
@@ -32,11 +33,13 @@ class BroadcastsController < ApplicationController
end end
def update def update
@broadcast.update(broadcast_params) unless params.has_key?(:broadcast)
@files = @broadcast.files.order("created_at DESC").paginate(page: 1) @broadcast.regenerate_token
redirect_to([@project, @broadcast], notice: t('.reset_notice')) and return
end
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] }) @broadcast.update(broadcast_params)
BroadcastsChannel.broadcast_file_upload_updates(@broadcast, @files, pagination_content) update_files_section
end end
def destroy def destroy
@@ -47,10 +50,29 @@ class BroadcastsController < ApplicationController
end end
end end
def destroy_file
authorize Broadcast
file = ActiveStorage::Attachment.find(params[:file_id])
file.destroy
update_files_section
end
private 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
def broadcast_params def broadcast_params
params.require(:broadcast).permit(:name, files: []) params.require(:broadcast).permit(:name, :shoot_location_time_zone, files: [])
end end
def set_project def set_project

View File

@@ -0,0 +1,10 @@
class CallbacksController < ApplicationController
skip_before_action :require_login
skip_after_action :verify_authorized, except: :index
skip_after_action :verify_policy_scoped, only: :index
skip_before_action :verify_authenticity_token
def create
render plain: params.inspect
end
end

View File

@@ -0,0 +1,13 @@
module MiscReleaseContext
extend ActiveSupport::Concern
def misc_releases
policy_scope(MiscRelease)
end
def set_misc_release
misc_release_id = params[:misc_release_id] || params[:id]
@misc_release = authorize misc_releases.find(misc_release_id)
end
end

View File

@@ -0,0 +1,33 @@
# frozen_string_literal: true
class ContractTemplates::DuplicatesController < ApplicationController
before_action :set_contract_template
def create
authorize(ContractTemplate)
new_contract_template = @contract_template.dup
new_contract_template.name = I18n.t('contract_templates.duplicate.name_prefix', template_name: @contract_template.name)
# Duplicate rich text fields
new_contract_template.body = @contract_template.body
new_contract_template.guardian_clause = @contract_template.guardian_clause
new_contract_template.signature_legal_text = @contract_template.signature_legal_text
if new_contract_template.save
redirect_to [:edit, new_contract_template]
else
redirect_to [@contract_template.project, :contract_templates], alert: t('.error')
end
end
private
def contract_templates
policy_scope(ContractTemplate)
end
def set_contract_template
@contract_template = contract_templates.find(params[:contract_template_id])
end
end

View File

@@ -16,7 +16,12 @@ class ContractTemplates::QrCodesController < ApplicationController
end end
def qr_code def qr_code
authorize QrCode.build_from_contract_template(@contract_template) if params[:multi_sign_ids].present?
contract_templates_group = authorize contract_templates.where(id: params[:multi_sign_ids]).order_by_recent
authorize QrCode.build_from_multiple_contract_templates(contract_templates_group, @contract_template.project)
else
authorize QrCode.build_from_contract_template(@contract_template)
end
end end
def download_attributes def download_attributes

View File

@@ -5,8 +5,10 @@ class ContractTemplatesController < ApplicationController
layout 'project' layout 'project'
before_action :set_project, except: [:destroy] before_action :set_project, except: [:destroy, :edit, :update]
before_action :set_contract_template, only: [:destroy] before_action :set_contract_template, only: [:destroy, :edit, :update]
before_action :set_project_from_contract_template, only: [:edit, :update]
before_action :show_splash_screen, only: :index
def index def index
@contract_templates = contract_templates.non_archived.order_by_name.paginate(page: params[:page]) @contract_templates = contract_templates.non_archived.order_by_name.paginate(page: params[:page])
@@ -31,6 +33,20 @@ class ContractTemplatesController < ApplicationController
end end
end end
def edit
@release_type = @contract_template.release_type
end
def update
@contract_template.attributes = contract_template_params
if @contract_template.save
redirect_to [@project, :contract_templates], notice: t('.notice')
else
render :edit
end
end
def destroy def destroy
@contract_template.archive @contract_template.archive
redirect_to [@contract_template.project, :contract_templates], alert: t('.archived_notice') redirect_to [@contract_template.project, :contract_templates], alert: t('.archived_notice')
@@ -38,6 +54,14 @@ class ContractTemplatesController < ApplicationController
private private
def set_project_from_contract_template
@project = @contract_template.project
end
def show_splash_screen
render :splash if contract_templates.non_archived.count.zero?
end
def set_contract_template def set_contract_template
@contract_template = authorize contract_templates.find(params[:id]) @contract_template = authorize contract_templates.find(params[:id])
end end
@@ -57,16 +81,20 @@ class ContractTemplatesController < ApplicationController
def contract_template_params def contract_template_params
params params
.require(:contract_template) .require(:contract_template)
.permit(:name, :release_type, :body, :guardian_clause, :fee, .permit(:name, :release_type, :body, :guardian_clause,
:signature_legal_text, :fee, :amendment_clause,
: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,
:question_5_text, :question_6_text, :question_5_text, :question_6_text,
:question_7_text, :question_8_text, :question_7_text, :question_8_text,
:question_9_text, :question_10_text) :question_9_text, :question_10_text,
:question_11_text, :question_12_text,
:question_13_text, :question_14_text,
:question_15_text)
end end
def download_attributes def download_attributes

View File

@@ -48,8 +48,10 @@ class ContractsController < ApplicationController
# Native release contracts must be generated on-the-fly; non-native releases have a contract attachment # Native release contracts must be generated on-the-fly; non-native releases have a contract attachment
if releasable.native? if releasable.native?
send_file contract.to_pdf, download_attributes send_file contract.to_pdf, download_attributes
else elsif policy(contract).show?
redirect_to releasable.contract.service_url redirect_to releasable.contract.service_url
else
raise Pundit::NotAuthorizedError
end end
end end
end end

View File

@@ -0,0 +1,40 @@
class MiscReleasesController < ApplicationController
include ProjectContext, MiscReleaseContext
before_action :set_project, only: [:index]
before_action :set_misc_release, only: [:destroy]
include ProjectLayout
def index
@misc_releases = filtered_misc_releases.order_by_recent.paginate(page: params[:page])
end
def destroy
@project = @misc_release.project
if @misc_release.destroy
redirect_to [@project, :misc_releases], alert: t(".alert")
end
end
private
def misc_releases
if @project
policy_scope(@project.misc_releases)
else
policy_scope(MiscRelease)
end
end
def filtered_misc_releases
results = misc_releases
if params[:query].present?
results = results.search(params[:query])
end
results
end
end

View File

@@ -60,7 +60,7 @@ class ProjectsController < ApplicationController
end end
def features_settings_params def features_settings_params
%i(appearance_release location_release material_release acquired_media_release music_release talent_release medical_release video_analysis) %i(appearance_release location_release material_release acquired_media_release music_release talent_release medical_release misc_release video_analysis)
end end
def project_params_with_current_account def project_params_with_current_account

View File

@@ -41,31 +41,70 @@ class Public::AcquiredMediaReleasesController < Public::BaseController
end end
end end
def person_params
%i[
person_first_name
person_last_name
person_phone
person_fax
person_email
person_title
person_address_street1
person_address_street2
person_address_city
person_address_state
person_address_zip
person_address_country
]
end
def guardian_params
%i[
guardian_first_name
guardian_last_name
guardian_phone
guardian_email
guardian_photo
guardian_address_street1
guardian_address_street2
guardian_address_city
guardian_address_state
guardian_address_zip
guardian_address_country
]
end
def second_guardian_params
%i[
guardian_2_first_name
guardian_2_last_name
guardian_2_phone
guardian_2_email
guardian_2_photo
guardian_2_address_street1
guardian_2_address_street2
guardian_2_address_city
guardian_2_address_state
guardian_2_address_zip
guardian_2_address_country
]
end
def acquired_media_release_params def acquired_media_release_params
params.require(:acquired_media_release).permit( params.require(:acquired_media_release).permit(person_params,
:name, guardian_params,
:description, second_guardian_params,
:person_first_name, :minor,
:person_last_name, :name,
:person_email, :description,
:person_title, :signature_base64,
:person_phone, :locale, :contract_template,
:person_fax, categories: [],
:person_address_street1, file_infos_attributes: %i[
:person_address_street2, filename
:person_address_city, content_type
:person_address_state, byte_size
:person_address_zip, ])
:person_address_country,
:signature_base64,
:locale, :contract_template,
categories: [],
file_infos_attributes: [
:filename,
:content_type,
:byte_size
]
)
end end
def acquired_media_release_params_with_locale def acquired_media_release_params_with_locale

View File

@@ -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

View File

@@ -39,11 +39,60 @@ class Public::AppearanceReleasesController < Public::BaseController
authorize appearance_releases.build(params) authorize appearance_releases.build(params)
end end
def person_params
%i[
person_first_name
person_last_name
person_phone
person_email
person_photo
person_address_street1
person_address_street2
person_address_city
person_address_state
person_address_zip
person_address_country
]
end
def guardian_params
%i[
guardian_first_name
guardian_last_name
guardian_phone
guardian_email
guardian_photo
guardian_address_street1
guardian_address_street2
guardian_address_city
guardian_address_state
guardian_address_zip
guardian_address_country
]
end
def second_guardian_params
%i[
guardian_2_first_name
guardian_2_last_name
guardian_2_phone
guardian_2_email
guardian_2_photo
guardian_2_address_street1
guardian_2_address_street2
guardian_2_address_city
guardian_2_address_state
guardian_2_address_zip
guardian_2_address_country
]
end
def appearance_release_params def appearance_release_params
params.require(:appearance_release).permit(:person_address, :person_first_name, :person_last_name, :person_phone, :person_email, :person_photo, params.require(:appearance_release).permit(person_params, guardian_params,
:guardian_address, :guardian_first_name, :guardian_last_name, :guardian_phone, :guardian_email, :guardian_photo, :minor, second_guardian_params,
:signature_base64, :person_date_of_birth, :minor, :signature_base64,
:locale, :contract_template,) :person_date_of_birth,
:locale, :contract_template)
end end
def appearance_release_params_with_locale def appearance_release_params_with_locale

View File

@@ -37,6 +37,10 @@ class Public::BroadcastsController < Public::BaseController
def set_broadcast def set_broadcast
@broadcast = Broadcast.find_by_token(params[:token]) @broadcast = Broadcast.find_by_token(params[:token])
unless @broadcast.present?
redirect_to [:new, :session], alert: t(".alert")
end
end end
class MultiViewBroadcast class MultiViewBroadcast

View File

@@ -0,0 +1,18 @@
class Public::ContractTemplatesController < Public::BaseController
skip_after_action :verify_authorized, :verify_policy_scoped
before_action :set_account, :set_project
def index
@contract_templates = @project.contract_templates.where(id: params[:contract_template_ids]).order_by_name.paginate(page: params[:page])
end
private
def set_project
@project = @account.projects.find(params[:project_id])
end
def set_account
@account = Account.find_by(slug: params[:account_id])
end
end

View File

@@ -45,6 +45,9 @@ class Public::MedicalReleasesController < Public::BaseController
.require(:medical_release) .require(:medical_release)
.permit( .permit(
person_params, person_params,
guardian_params,
second_guardian_params,
:minor,
:signature_base64, :signature_base64,
:locale, :locale,
:contract_template, :contract_template,
@@ -53,22 +56,56 @@ class Public::MedicalReleasesController < Public::BaseController
:question_5_answer, :question_6_answer, :question_5_answer, :question_6_answer,
:question_7_answer, :question_8_answer, :question_7_answer, :question_8_answer,
:question_9_answer, :question_10_answer, :question_9_answer, :question_10_answer,
photos: [], :question_11_answer, :question_12_answer,
:question_13_answer, :question_14_answer,
:question_15_answer, photos: [],
) )
end end
def person_params def person_params
[ %i[
:person_first_name, person_first_name
:person_last_name, person_last_name
:person_phone, person_phone
:person_email, person_email
:person_address_street1, person_address_street1
:person_address_street2, person_address_street2
:person_address_city, person_address_city
:person_address_state, person_address_state
:person_address_zip, person_address_zip
:person_address_country, person_address_country
]
end
def guardian_params
%i[
guardian_first_name
guardian_last_name
guardian_phone
guardian_email
guardian_photo
guardian_address_street1
guardian_address_street2
guardian_address_city
guardian_address_state
guardian_address_zip
guardian_address_country
]
end
def second_guardian_params
%i[
guardian_2_first_name
guardian_2_last_name
guardian_2_phone
guardian_2_email
guardian_2_photo
guardian_2_address_street1
guardian_2_address_street2
guardian_2_address_city
guardian_2_address_state
guardian_2_address_zip
guardian_2_address_country
] ]
end end

View File

@@ -0,0 +1,120 @@
class Public::MiscReleasesController < Public::BaseController
before_action :set_account, :set_project, :set_contract_template
def new
@misc_release = build_misc_release
end
def create
@misc_release = build_misc_release(misc_release_params_with_locale_and_contract_template)
if @misc_release.save(context: :native)
if @misc_release.contract_template.present?
AttachContractToReleasableJob.perform_later(@misc_release)
end
log_create_analytics
else
render :new
end
end
private
def set_project
@project = @account.projects.find(params[:project_id])
end
def set_account
@account = Account.find_by(slug: params[:account_id])
end
def set_contract_template
@contract_template = @project.contract_templates.find(params[:contract_template_id])
end
def misc_releases
policy_scope(@project.misc_releases)
end
def build_misc_release(params = {})
authorize misc_releases.build(params)
end
def misc_release_params
params
.require(:misc_release)
.permit(
person_params,
guardian_params,
questionnaire_params,
:signature_base64,
:locale,
:contract_template,
photos: [],
)
end
def person_params
[
:person_first_name,
:person_last_name,
:person_phone,
:person_email,
:person_address_street1,
:person_address_street2,
:person_address_city,
:person_address_state,
:person_address_zip,
:person_address_country,
]
end
def guardian_params
[
:guardian_first_name,
:guardian_last_name,
:guardian_phone,
:guardian_email,
:minor,
:guardian_address_street1,
:guardian_address_street2,
:guardian_address_city,
:guardian_address_state,
:guardian_address_zip,
:guardian_address_country,
:guardian_photo
]
end
def questionnaire_params
[
:question_1_answer,
:question_2_answer,
:question_3_answer,
:question_4_answer,
:question_5_answer,
:question_6_answer,
:question_7_answer,
:question_8_answer,
:question_9_answer,
:question_10_answer,
:question_11_answer,
:question_12_answer,
:question_13_answer,
:question_14_answer,
:question_15_answer,
]
end
def misc_release_params_with_locale
misc_release_params.merge(locale: I18n.locale)
end
def misc_release_params_with_locale_and_contract_template
misc_release_params_with_locale.merge(contract_template: @contract_template)
end
def log_create_analytics
TrackAnalyticsJob.perform_later(nil, nil, :track_create_native_release, release_type: MiscRelease.to_s, account: @account, user_agent: request.user_agent, user_ip: request.remote_ip)
end
end

View File

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

View File

@@ -11,7 +11,9 @@ class ReleaseTemplateImportsController < ApplicationController
templates = [] templates = []
filtered_contract_templates.each do |contract_template| filtered_contract_templates.each do |contract_template|
next if contract_template.duplicated? || contract_template.project == @project next if contract_template.duplicated? ||
contract_template.archived? ||
contract_template.project == @project
already_imported = contract_template.duplicates.non_archived.pluck(:project_id).include?(@project.id) already_imported = contract_template.duplicates.non_archived.pluck(:project_id).include?(@project.id)
templates << OpenStruct.new(template: contract_template, already_imported?: already_imported) templates << OpenStruct.new(template: contract_template, already_imported?: already_imported)

View File

@@ -14,6 +14,10 @@ class StreamNotificationsController < ApplicationController
when "video.live_stream.recording" when "video.live_stream.recording"
@broadcast.streamer_recording! @broadcast.streamer_recording!
notify_users notify_users
when "video.asset.ready"
full_live_stream_playback_uid = notification.dig(:data, :playback_ids, 0, :id)
@broadcast.update(full_live_stream_playback_uid: full_live_stream_playback_uid)
notify_users
when "video.live_stream.active" when "video.live_stream.active"
@broadcast.active! @broadcast.active!
notify_users notify_users
@@ -28,8 +32,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")
@@ -58,11 +63,17 @@ class StreamNotificationsController < ApplicationController
end end
def set_broadcast def set_broadcast
if notification_type == "video.asset.static_renditions.ready" case notification_type
when "video.asset.static_renditions.ready", "video.asset.ready"
live_stream_id = notification.dig(:stream_notification, :data, :live_stream_id) live_stream_id = notification.dig(:stream_notification, :data, :live_stream_id)
@broadcast = Broadcast.find_by!(stream_uid: live_stream_id) @broadcast = Broadcast.find_by(stream_uid: live_stream_id)
else else
@broadcast = Broadcast.find_by!(stream_uid: notification_object_id) @broadcast = Broadcast.find_by(stream_uid: notification_object_id)
end
if @broadcast.nil?
logger.info "Ignoring broadcast from other environment. Type = #{notification_type}. Id = #{live_stream_id} / #{notification_object_id}"
head :ok
end end
end end

View File

@@ -61,15 +61,67 @@ class TalentReleasesController < ApplicationController
end end
end end
def person_params
%i[
person_first_name
person_last_name
person_phone
person_email
person_address_street1
person_address_street2
person_address_city
person_address_state
person_address_zip
person_address_country
]
end
def guardian_params
%i[
guardian_first_name
guardian_last_name
guardian_phone
guardian_email
minor
guardian_address_street1
guardian_address_street2
guardian_address_city
guardian_address_state
guardian_address_zip
guardian_address_country
guardian_photo
]
end
def second_guardian_params
%i[
guardian_2_first_name
guardian_2_last_name
guardian_2_phone
guardian_2_email
guardian_2_address_street1
guardian_2_address_street2
guardian_2_address_city
guardian_2_address_state
guardian_2_address_zip
guardian_2_address_country
guardian_2_photo
]
end
def talent_release_params def talent_release_params
params.require(:talent_release).permit( params.require(:talent_release).permit(person_params,
:person_first_name, :person_last_name, :person_phone, :guardian_photo, :person_email, guardian_params,
:person_address_street1, :person_address_street2, :person_address_city, :person_address_state, :person_address_zip, :person_address_country, second_guardian_params,
:guardian_first_name, :guardian_last_name, :guardian_phone, :guardian_email, :minor, :contract, { photos: [] },
:guardian_address_street1, :guardian_address_street2, :guardian_address_city, :guardian_address_state, :guardian_address_zip, :guardian_address_country, :applicable_medium_id,
:contract, { photos: [] }, :applicable_medium_text,
:applicable_medium_id, :applicable_medium_text, :territory_id, :territory_text, :term_id, :term_text, :restriction_id, :restriction_text :territory_id,
) :territory_text,
:term_id,
:term_text,
:restriction_id,
:restriction_text)
end end
def build_talent_release(attrs = {}) def build_talent_release(attrs = {})

View File

@@ -0,0 +1,81 @@
class TaskRequestsController < ApplicationController
layout "project"
before_action :set_project
before_action :build_task_request, only: [:new, :create]
before_action :set_task_request, only: [:show, :edit, :update, :cancel]
before_action :show_splash_screen, only: :index
def index
@task_requests = task_requests.order_by_recent.paginate(page: params[:page])
end
def new
end
def create
@task_request.attributes = task_request_params_with_email
if @task_request.save
log_create_analytics
taskme_url = url_for([:admin, @task_request])
SubmitHubspotTaskRequestFormJob.perform_later(@task_request.user_email, taskme_url)
else
render :new
end
end
def show
@files = @task_request.files.paginate(page: params[:page])
end
def edit
end
def update
if @task_request.update(task_request_params)
redirect_to [@project, :task_requests], notice: t(".notice")
else
render :edit
end
end
def cancel
@task_request.cancelled!
redirect_to [@project, :task_requests], notice: t(".notice")
end
private
def show_splash_screen
render :splash if task_requests.count.zero?
end
def task_request_params
params.require(:task_request).permit(:description, :deadline, :time_allowed, :additional_notes, files: [])
end
def task_request_params_with_email
task_request_params.merge(user_email: Current.user.email)
end
def set_project
@project = policy_scope(Project).find(params[:project_id])
end
def set_task_request
@task_request = authorize policy_scope(TaskRequest).find(params[:id])
end
def task_requests
authorize policy_scope(@project.task_requests)
end
def build_task_request
@task_request = authorize @project.task_requests.build
end
def log_create_analytics
TrackAnalyticsJob.perform_later(Current.user, Current.account, :track_create_task_request, user_agent: request.user_agent, user_ip: request.remote_ip)
end
end

View File

@@ -0,0 +1,19 @@
class TasksController < ApplicationController
before_action :set_project
include ProjectLayout
def index
@tasks = task_requests.completed.order_by_recent.paginate(page: params[:page])
end
private
def set_project
@project = policy_scope(Project).find(params[:project_id])
end
def task_requests
authorize policy_scope(@project.task_requests)
end
end

View File

@@ -3,6 +3,7 @@ class VideosController < ApplicationController
before_action :set_project, only: [:index, :new, :create, :landing] before_action :set_project, only: [:index, :new, :create, :landing]
before_action :set_video, only: [:edit, :update] before_action :set_video, only: [:edit, :update]
before_action :show_splash_screen, only: :index
def landing def landing
authorize Video, :new? authorize Video, :new?
@@ -60,6 +61,10 @@ class VideosController < ApplicationController
private private
def show_splash_screen
render :splash if videos.count.zero?
end
def set_project def set_project
@project = policy_scope(Project).find(params[:project_id]) @project = policy_scope(Project).find(params[:project_id])
end end

View File

@@ -7,8 +7,8 @@ module DescriptionListHelper
safe_join(tags) safe_join(tags)
end end
def description_list_pair_for(record, attribute, append: nil) def description_list_pair_for(record, attribute, append: nil, custom_label: nil)
term = translation_for(record, attribute) term = custom_label.nil? ? translation_for(record, attribute) : custom_label
definition = record.send(attribute) definition = record.send(attribute)
description_list_pair(term, definition, append: append) description_list_pair(term, definition, append: append)

View File

@@ -2,7 +2,7 @@ module DropzoneHelper
def dropzone_placeholder_message_for(releasable) def dropzone_placeholder_message_for(releasable)
case releasable.model_name.param_key case releasable.model_name.param_key
when "acquired_media_release" when "acquired_media_release"
"To Add Photos & Videos to the release:<br>Drag & Drop Files<br>or<br>Click or Tap here to browse photos and connect to Camera" '(Optional) To add the licensed photos or videos ("Property") to this release:<br>Drag & Drop Files<br>or<br>Click or Tap here to browse photos and connect to Camera'
when "material_release" when "material_release"
t 'material_releases.form.photos.dropzone_label' t 'material_releases.form.photos.dropzone_label'
when "music_release" when "music_release"
@@ -11,6 +11,8 @@ module DropzoneHelper
t 'location_releases.form.photos.dropzone_label' t 'location_releases.form.photos.dropzone_label'
when "directory" when "directory"
"To Add Files to the Folder:<br>Drag & Drop Files<br>or<br>Click or Tap here to browse files" "To Add Files to the Folder:<br>Drag & Drop Files<br>or<br>Click or Tap here to browse files"
when "task_request"
"To Add Files for the Task:<br>Drag & Drop Files<br>or<br>Click or Tap here to browse files"
else else
"To Add Photos to the release:<br>Drag & Drop Files<br>or<br>Click or Tap here to browse photos and connect to Camera" "To Add Photos to the release:<br>Drag & Drop Files<br>or<br>Click or Tap here to browse photos and connect to Camera"
end end

View File

@@ -5,4 +5,12 @@ module TooltipHelper
concat tag.div(class: "tooltip-inner") concat tag.div(class: "tooltip-inner")
end end
end end
def get_approval_data_for_releasable(release)
if release.approved_by_user_name.present?
"#{release.approved_by_user_name} [#{release.approved_by_user_email}]"
else
release.approved_by_user_email
end
end
end end

View File

@@ -13,10 +13,13 @@ module WordmarkHelper
css += options[:class].to_s css += options[:class].to_s
content_tag(:div, class: css) do content_tag(:div, class: css) do
safe_join [ elements = [
content_tag(:span, t("shared.#{product_name}")), content_tag(:span, t("shared.#{product_name}")),
content_tag(:span, t("shared.me")) content_tag(:span, t("shared.me"))
] ]
prefix = options[:prefix]
elements.unshift content_tag(:span, "#{prefix} ") unless prefix.blank?
safe_join elements
end end
end end
end end

View File

@@ -1,5 +1,6 @@
$(document).on("turbolinks:load", () => { $(document).on("turbolinks:load", () => {
$('.datepicker-control').datepicker({ $('.datepicker-control').datepicker({
format: "yyyy-mm-dd" format: "yyyy-mm-dd",
todayHighlight: true
}); });
}); });

View File

@@ -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,9 +20,14 @@ 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) @download.file.attach(io: File.open(zipfile_name), filename: "#{@folder_name}.zip")
end end
rescue StandardError => e rescue StandardError => e
Rails.logger.error("Failed to generate download for project (##{project.id}) with release type #{release_type}\n" + e.message) Rails.logger.error("Failed to generate download for project (##{project.id}) with release type #{release_type}\n" + e.message)
@@ -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

View File

@@ -1,12 +1,14 @@
class SubmitHubspotFormJob < ApplicationJob class SubmitHubspotFormJob < ApplicationJob
queue_as :default queue_as :default
def perform(email, company_name, additional_params = {}) def perform(first_name, last_name, email, company_name, additional_params = {})
hubspot_form_guid = ENV["HUBSPOT_FORM_GUID"] hubspot_form_guid = ENV["HUBSPOT_FORM_GUID"]
return unless hubspot_form_guid.present? return unless hubspot_form_guid.present?
submission_params = { submission_params = {
email: email, first_name: first_name,
last_name: last_name,
email: email,
company: company_name company: company_name
}.merge(additional_params) }.merge(additional_params)

View File

@@ -0,0 +1,18 @@
class SubmitHubspotTaskRequestFormJob < ApplicationJob
queue_as :default
def perform(user_email, taskme_url)
hubspot_task_request_form_guid = ENV["HUBSPOT_TASK_REQUEST_FORM_GUID"]
return unless hubspot_task_request_form_guid.present?
submission_params = {
email: user_email,
taskme_url: taskme_url
}
form = Hubspot::Form.new("guid" => hubspot_task_request_form_guid)
is_form_sumitted = form.submit(submission_params)
raise StandardError.new "Failed to submit the task request hubspot form data: #{is_form_sumitted}" unless is_form_sumitted
end
end

View File

@@ -54,8 +54,10 @@ class Account < ApplicationRecord
Download.where(project: projects), Download.where(project: projects),
User.joins(:project_memberships).where(project_memberships: { project: projects }), User.joins(:project_memberships).where(project_memberships: { project: projects }),
Broadcast.where(project: projects), Broadcast.where(project: projects),
TaskRequest.where(project: projects),
ZoomMeeting.where(project: projects), ZoomMeeting.where(project: projects),
MedicalRelease.where(project: projects), MedicalRelease.where(project: projects),
MiscRelease.where(project: projects),
MatchingRequest.where(project: projects), MatchingRequest.where(project: projects),
self self
])).sum(:byte_size).to_f ])).sum(:byte_size).to_f
@@ -81,6 +83,10 @@ class Account < ApplicationRecord
plan_uid.to_s == "me_suite" || plan_uid.to_s == "releaseme" plan_uid.to_s == "me_suite" || plan_uid.to_s == "releaseme"
end end
def taskme_enabled?
ENV["TASKME_ENABLED"] && (plan_uid.to_s == "me_suite" || plan_uid.to_s == "taskme")
end
def plan_name def plan_name
case plan_uid.to_s case plan_uid.to_s
when "deliverme" when "deliverme"
@@ -89,6 +95,8 @@ class Account < ApplicationRecord
"DirectME" "DirectME"
when "releaseme" when "releaseme"
"ReleaseME" "ReleaseME"
when "taskme"
"TaskME"
when "me_suite" when "me_suite"
"ME Suite" "ME Suite"
end end

View File

@@ -9,6 +9,18 @@ class AcquiredMediaRelease < ApplicationRecord
include Signable include Signable
include Syncable include Syncable
include PersonName include PersonName
include CsvExportable
include Approvable
include GuardianPhotoable
include SecondGuardianPhotoable
include GuardianName
include SecondGuardianName
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
@@ -25,6 +37,38 @@ class AcquiredMediaRelease < ApplicationRecord
%w(person_address_country country) %w(person_address_country country)
] ]
composed_of :guardian_address,
class_name: 'Address',
mapping: [
%w[guardian_address_street1 street1],
%w[guardian_address_street2 street2],
%w[guardian_address_city city],
%w[guardian_address_state state],
%w[guardian_address_zip zip],
%w[guardian_address_country country]
]
composed_of :guardian_2_address,
class_name: 'Address',
mapping: [
%w[guardian_2_address_street1 street1],
%w[guardian_2_address_street2 street2],
%w[guardian_2_address_city city],
%w[guardian_2_address_state state],
%w[guardian_2_address_zip zip],
%w[guardian_2_address_country country]
]
# We don't care for the argument but method WILL receive option name
# when called from inside with_option block, hence * argument
def self.face_photo_acceptable_content_types(*)
['image/png', 'image/jpeg']
end
def self.acceptable_import_file_extensions
['.png', '.jpeg', '.jpg', '.pdf']
end
validates :name, presence: true validates :name, presence: true
validates :person_email, email: true, allow_blank: true validates :person_email, email: true, allow_blank: true
@@ -46,8 +90,8 @@ class AcquiredMediaRelease < ApplicationRecord
# CATEGORIES = ["Artwork", "Film Footage", "Video Footage", "Still Photograph"].freeze # CATEGORIES = ["Artwork", "Film Footage", "Video Footage", "Still Photograph"].freeze
CATEGORIES = ["Film Footage", "Video Footage", "Still Photograph"].freeze CATEGORIES = ["Film Footage", "Video Footage", "Still Photograph"].freeze
def minor? def second_guardian_present?
false guardian_2_first_name.present?
end end
def contact_person def contact_person
@@ -57,4 +101,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

View File

@@ -15,7 +15,7 @@ class AppHost
end end
def domain_with_port def domain_with_port
[domain, port].compact.join(":") [domain, port].reject(&:blank?).compact.join(":")
end end
def protocol def protocol

View File

@@ -12,10 +12,54 @@ class AppearanceRelease < ApplicationRecord
include Taggable include Taggable
include PersonName include PersonName
include GuardianPhotoable include GuardianPhotoable
include SecondGuardianPhotoable
include GuardianName include GuardianName
include SecondGuardianName
include CsvExportable
include Approvable
class << self
def custom_csv_exportable_headers
%i[name contact_info]
end
end
has_one_attached :person_photo has_one_attached :person_photo
composed_of :person_address,
class_name: 'Address',
mapping: [
%w[person_address_street1 street1],
%w[person_address_street2 street2],
%w[person_address_city city],
%w[person_address_state state],
%w[person_address_zip zip],
%w[person_address_country country]
]
composed_of :guardian_address,
class_name: 'Address',
mapping: [
%w[guardian_address_street1 street1],
%w[guardian_address_street2 street2],
%w[guardian_address_city city],
%w[guardian_address_state state],
%w[guardian_address_zip zip],
%w[guardian_address_country country]
]
composed_of :guardian_2_address,
class_name: 'Address',
mapping: [
%w[guardian_2_address_street1 street1],
%w[guardian_2_address_street2 street2],
%w[guardian_2_address_city city],
%w[guardian_2_address_state state],
%w[guardian_2_address_zip zip],
%w[guardian_2_address_country country]
]
# These validations apply to all releases # These validations apply to all releases
validates :person_email, email: true, allow_blank: true validates :person_email, email: true, allow_blank: true
validates :person_first_name, :person_last_name, presence: true validates :person_first_name, :person_last_name, presence: true
@@ -71,7 +115,18 @@ class AppearanceRelease < ApplicationRecord
scope :having_no_person_photo, -> { left_joins(:person_photo_attachment).group(:id).having('COUNT(active_storage_attachments) = 0') } scope :having_no_person_photo, -> { left_joins(:person_photo_attachment).group(:id).having('COUNT(active_storage_attachments) = 0') }
scope :with_person_name, ->(name) { where('person_first_name ILIKE ? OR person_last_name ILIKE ?', "%#{name}%") } scope :with_person_name, ->(name) { where('person_first_name ILIKE ? OR person_last_name ILIKE ?', "%#{name}%") }
searchable_on %i[person_first_name person_last_name person_address person_email person_phone] searchable_on %i[
person_first_name
person_last_name
person_address_street1
person_address_street2
person_address_city
person_address_state
person_address_zip
person_address_country
person_email
person_phone
]
# All releases must respond to the following messages # All releases must respond to the following messages
def name def name
@@ -98,6 +153,10 @@ class AppearanceRelease < ApplicationRecord
true true
end end
def second_guardian_present?
self.guardian_2_first_name.present?
end
def contract_file_name def contract_file_name
"#{project.name.parameterize}_#{contract_template.release_type}_#{(signed_at || created_at).strftime('%Y.%m.%d')}_#{release_number}_#{filename_suffix.parameterize}" "#{project.name.parameterize}_#{contract_template.release_type}_#{(signed_at || created_at).strftime('%Y.%m.%d')}_#{release_number}_#{filename_suffix.parameterize}"
end end

View File

@@ -30,6 +30,10 @@ class Broadcast < ApplicationRecord
"https://stream.mux.com/#{stream_playback_uid}.m3u8" "https://stream.mux.com/#{stream_playback_uid}.m3u8"
end end
def full_live_stream_playback_url
full_live_stream_playback_uid.blank? ? stream_playback_url : "https://stream.mux.com/#{full_live_stream_playback_uid}.m3u8"
end
def stream_server_url def stream_server_url
ENV['MUX_BROADCAST_SERVER_URL'] ENV['MUX_BROADCAST_SERVER_URL']
end end

View File

@@ -14,6 +14,6 @@ class BroadcastRecording < ApplicationRecord
end end
def download_file_name def download_file_name
"#{broadcast_name}_Date_#{created_at.strftime("%Y-%m-%d")}_Time_#{created_at.strftime("%T")}".parameterize "#{broadcast_name}_Date_#{created_at.in_time_zone(broadcast.shoot_location_time_zone).strftime("%Y-%m-%d")}_Time_#{created_at.in_time_zone(broadcast.shoot_location_time_zone).strftime("%T")}".parameterize
end end
end end

View File

@@ -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

View File

@@ -0,0 +1,17 @@
module Approvable
extend ActiveSupport::Concern
included do
def approve_by(user)
return unless approved_at.nil?
self.approved_by_user_name = user.full_name
self.approved_by_user_email = user.email
self.approved_at = Time.zone.now
end
def approved?
self.approved_at.present?
end
end
end

View File

@@ -0,0 +1,56 @@
# frozen_string_literal: true
module CsvExportable
extend ActiveSupport::Concern
COMMON_HEADERS = %i[approved? 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

View File

@@ -0,0 +1,20 @@
module SecondGuardianName
extend ActiveSupport::Concern
included do
def guardian_2_name
"#{guardian_2_first_name} #{guardian_2_last_name}".titleize
end
def guardian_2_name=(value)
if value.include?(' ')
split = value.split(" ", 2)
self.guardian_2_first_name = split.first
self.guardian_2_last_name = split.last
else
self.guardian_2_first_name = value
self.guardian_2_last_name = "(Not Given)"
end
end
end
end

View File

@@ -0,0 +1,9 @@
module SecondGuardianPhotoable
extend ActiveSupport::Concern
included do
has_one_attached :guardian_2_photo
validates :guardian_2_photo, content_type: ["image/png", "image/jpeg"]
end
end

View File

@@ -29,6 +29,10 @@ class Contract
} }
end end
def medical_release?
@releasable.instance_of?(MedicalRelease)
end
private private
def contract_template def contract_template

View File

@@ -5,6 +5,8 @@ class ContractTemplate < ApplicationRecord
include Syncable include Syncable
include PgSearch include PgSearch
NUMBER_OF_CUSTOM_FIELDS = 15
belongs_to :project belongs_to :project
belongs_to :parent, class_name: 'ContractTemplate', optional: true belongs_to :parent, class_name: 'ContractTemplate', optional: true
has_many :duplicates, class_name: 'ContractTemplate', foreign_key: 'parent_id' has_many :duplicates, class_name: 'ContractTemplate', foreign_key: 'parent_id'
@@ -14,10 +16,13 @@ class ContractTemplate < ApplicationRecord
has_many :location_releases, dependent: :restrict_with_error has_many :location_releases, dependent: :restrict_with_error
has_many :material_releases, dependent: :restrict_with_error has_many :material_releases, dependent: :restrict_with_error
has_many :medical_releases, dependent: :restrict_with_error has_many :medical_releases, dependent: :restrict_with_error
has_many :misc_releases, dependent: :restrict_with_error
monetize :fee_cents monetize :fee_cents
has_rich_text :body has_rich_text :body
has_rich_text :guardian_clause has_rich_text :guardian_clause
has_rich_text :signature_legal_text
has_rich_text :amendment_clause
validates :name, presence: true validates :name, presence: true
validates :release_type, presence: true validates :release_type, presence: true
@@ -39,6 +44,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
@@ -51,7 +58,25 @@ class ContractTemplate < ApplicationRecord
parent.present? parent.present?
end end
def archived?
archived_at.present?
end
def archive def archive
update(archived_at: Time.zone.now) update(archived_at: Time.zone.now)
end end
def has_questionnaire?
(1..NUMBER_OF_CUSTOM_FIELDS).any? { |n| public_send("question_#{n}_text").presence }
end
def editable?
releases.size.zero?
end
def attributes
result = super()
result[:signature_legal_text] = signature_legal_text.as_json
result
end
end end

View File

@@ -10,6 +10,15 @@ class LocationRelease < ApplicationRecord
include Syncable include Syncable
include Taggable include Taggable
include PersonName include PersonName
include CsvExportable
include Approvable
include Amendmenable
class << self
def custom_csv_exportable_headers
%i[name address]
end
end
composed_of :address, composed_of :address,
mapping: [ mapping: [

View File

@@ -10,8 +10,16 @@ class MaterialRelease < ApplicationRecord
include Syncable include Syncable
include Taggable include Taggable
include PersonName include PersonName
include CsvExportable
composed_of :person_address, include Approvable
class << self
def custom_csv_exportable_headers
%i[name]
end
end
composed_of :person_address,
class_name: "Address", class_name: "Address",
mapping: [ mapping: [
%w(person_address_street1 street1), %w(person_address_street1 street1),
@@ -30,15 +38,15 @@ class MaterialRelease < ApplicationRecord
validates :signature, attached: true validates :signature, attached: true
end end
searchable_on %i[ searchable_on %i[
name name
person_address_street1 person_address_street2 person_address_city person_address_state person_address_zip person_address_country person_address_street1 person_address_street2 person_address_city person_address_state person_address_zip person_address_country
] ]
def contact_person def contact_person
@contact_person ||= Contact.new(person_name, person_address, person_email, person_phone) @contact_person ||= Contact.new(person_name, person_address, person_email, person_phone)
end end
def minor? def minor?
false false
end end

View File

@@ -7,16 +7,52 @@ class MedicalRelease < ApplicationRecord
include Signable include Signable
include Syncable include Syncable
include PersonName include PersonName
include GuardianPhotoable
include SecondGuardianPhotoable
include GuardianName
include SecondGuardianName
include CsvExportable
include Approvable
composed_of :person_address, class << self
def custom_csv_exportable_headers
%i[name contact_info]
end
end
NUMBER_OF_CUSTOM_FIELDS = 15
composed_of :person_address,
class_name: "Address", class_name: "Address",
mapping: [ mapping: [
%w(person_address_street1 street1), %w[person_address_street1 street1],
%w(person_address_street2 street2), %w[person_address_street2 street2],
%w(person_address_city city), %w[person_address_city city],
%w(person_address_state state), %w[person_address_state state],
%w(person_address_zip zip), %w[person_address_zip zip],
%w(person_address_country country) %w[person_address_country country]
]
composed_of :guardian_address,
class_name: 'Address',
mapping: [
%w[guardian_address_street1 street1],
%w[guardian_address_street2 street2],
%w[guardian_address_city city],
%w[guardian_address_state state],
%w[guardian_address_zip zip],
%w[guardian_address_country country]
]
composed_of :guardian_2_address,
class_name: 'Address',
mapping: [
%w[guardian_2_address_street1 street1],
%w[guardian_2_address_street2 street2],
%w[guardian_2_address_city city],
%w[guardian_2_address_state state],
%w[guardian_2_address_zip zip],
%w[guardian_2_address_country country]
] ]
def self.face_photo_acceptable_content_types def self.face_photo_acceptable_content_types
@@ -26,9 +62,16 @@ class MedicalRelease < ApplicationRecord
# These validations apply to all releases # These validations apply to all releases
validates :person_first_name, :person_last_name, presence: true validates :person_first_name, :person_last_name, presence: true
validates :person_email, email: true, allow_blank: true validates :person_email, email: true, allow_blank: true
validate :valid_answers
acts_as_taggable_on :internal_tags, :tags acts_as_taggable_on :internal_tags, :tags
# These validations apply to releases being signed by a minor
with_options if: :minor? do
validates :guardian_email, email: true, allow_blank: true
validates :guardian_2_email, email: true, allow_blank: true
end
# These validations apply to releases created natively by the system (i.e. not imported from elsewhere) # These validations apply to releases created natively by the system (i.e. not imported from elsewhere)
with_options on: :native do with_options on: :native do
validates :signature, attached: true validates :signature, attached: true
@@ -61,11 +104,18 @@ class MedicalRelease < ApplicationRecord
false false
end end
def minor?
false
end
def contract_file_name def contract_file_name
"#{project.name.parameterize}_#{contract_template.release_type}_#{(signed_at || created_at).strftime("%Y.%m.%d")}_#{release_number}_#{filename_suffix.parameterize}" "#{project.name.parameterize}_#{contract_template.release_type}_#{(signed_at || created_at).strftime("%Y.%m.%d")}_#{release_number}_#{filename_suffix.parameterize}"
end end
private
def valid_answers
(1..ContractTemplate::NUMBER_OF_CUSTOM_FIELDS).each do |index|
if contract_template && contract_template["question_#{index}_text"].present? &&
public_send("question_#{index}_answer").blank?
errors.add("question_#{index}", I18n.t('medical_releases.custom_validation_errors.question_answer_is_required'))
end
end
end
end end

View File

@@ -0,0 +1,96 @@
class MiscRelease < ApplicationRecord
include Contractable
include Notable
include Photoable
include Releasable
include Searchable
include Signable
include Syncable
include PersonName
include GuardianName
include GuardianPhotoable
include CsvExportable
include Approvable
class << self
def custom_csv_exportable_headers
%i[name contact_info]
end
end
NUMBER_OF_CUSTOM_FIELDS = 15
composed_of :person_address,
class_name: "Address",
mapping: [
%w(person_address_street1 street1),
%w(person_address_street2 street2),
%w(person_address_city city),
%w(person_address_state state),
%w(person_address_zip zip),
%w(person_address_country country)
]
composed_of :guardian_address,
class_name: "Address",
mapping: [
%w(guardian_address_street1 street1),
%w(guardian_address_street2 street2),
%w(guardian_address_city city),
%w(guardian_address_state state),
%w(guardian_address_zip zip),
%w(guardian_address_country country)
]
def self.face_photo_acceptable_content_types
["image/png", "image/jpeg"]
end
# These validations apply to all releases
validates :person_first_name, :person_last_name, presence: true
validates :person_email, email: true, allow_blank: true
acts_as_taggable_on :internal_tags, :tags
# These validations apply to releases created natively by the system (i.e. not imported from elsewhere)
with_options on: :native do
validates :signature, attached: true
end
# These validations apply to releases imported to the system from an outside source
with_options on: :non_native do
validates :contract, attached: true
end
with_options if: :minor? do
validates :guardian_first_name, :guardian_last_name, presence: true
validates :guardian_phone, presence: true
end
searchable_on %i[
person_first_name person_last_name person_email person_phone
person_address_street1 person_address_street2 person_address_city person_address_state person_address_zip person_address_country
guardian_address_street1 guardian_address_street2 guardian_address_city guardian_address_state guardian_address_zip guardian_address_country
]
# All releases must respond to the following messages
def name
person_name
end
def filename_suffix
"#{person_last_name} #{person_first_name}"
end
def contact_person
@contact_person ||= Contact.new(person_name, person_address, person_email, person_phone)
end
def uses_edl?
false
end
def contract_file_name
"#{project.name.parameterize}_#{contract_template.release_type}_#{(signed_at || created_at).strftime("%Y.%m.%d")}_#{release_number}_#{filename_suffix.parameterize}"
end
end

View File

@@ -7,7 +7,15 @@ class MusicRelease < ApplicationRecord
include Searchable include Searchable
include Taggable include Taggable
include PersonName include PersonName
include CsvExportable
include Approvable
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
has_many :publishers, dependent: :destroy has_many :publishers, dependent: :destroy
@@ -72,6 +80,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

View File

@@ -3,8 +3,8 @@ class Project < ApplicationRecord
include Filterable include Filterable
include Syncable include Syncable
SIGNABLE_RELEASE_TYPES = %w(talent appearance acquired_media location material medical) SIGNABLE_RELEASE_TYPES = %w(talent appearance acquired_media location material medical misc)
AVAILABLE_RELEASE_TYPES = %w(appearance location material acquired_media talent music medical) AVAILABLE_RELEASE_TYPES = %w(appearance location material acquired_media talent music medical misc)
belongs_to :account belongs_to :account
has_many :acquired_media_releases, dependent: :destroy has_many :acquired_media_releases, dependent: :destroy
@@ -14,6 +14,7 @@ class Project < ApplicationRecord
has_many :music_releases, dependent: :destroy has_many :music_releases, dependent: :destroy
has_many :talent_releases, dependent: :destroy has_many :talent_releases, dependent: :destroy
has_many :medical_releases, dependent: :destroy has_many :medical_releases, dependent: :destroy
has_many :misc_releases, dependent: :destroy
has_many :videos, dependent: :destroy has_many :videos, dependent: :destroy
has_many :imports, dependent: :destroy has_many :imports, dependent: :destroy
has_many :contract_templates, dependent: :destroy has_many :contract_templates, dependent: :destroy
@@ -23,6 +24,7 @@ class Project < ApplicationRecord
has_many :downloads, dependent: :destroy has_many :downloads, dependent: :destroy
has_many :broadcasts, dependent: :destroy has_many :broadcasts, dependent: :destroy
has_many :zoom_meetings, dependent: :destroy has_many :zoom_meetings, dependent: :destroy
has_many :task_requests, dependent: :destroy
accepts_nested_attributes_for :project_memberships accepts_nested_attributes_for :project_memberships
@@ -35,6 +37,7 @@ class Project < ApplicationRecord
music_release: false, music_release: false,
talent_release: false, talent_release: false,
medical_release: false, medical_release: false,
misc_release: false,
video_analysis: false, video_analysis: false,
} }
end end
@@ -68,6 +71,7 @@ class Project < ApplicationRecord
music_release: true, music_release: true,
talent_release: true, talent_release: true,
medical_release: true, medical_release: true,
misc_release: true,
video_analysis: true, video_analysis: true,
} }
when "nat_geo" when "nat_geo"
@@ -80,6 +84,7 @@ class Project < ApplicationRecord
music_release: true, music_release: true,
talent_release: true, talent_release: true,
medical_release: true, medical_release: true,
misc_release: true,
video_analysis: true, video_analysis: true,
} }
else else

View File

@@ -10,7 +10,19 @@ class QrCode
url = Rails.application.routes.url_helpers.url_for(route) url = Rails.application.routes.url_helpers.url_for(route)
filename = [contract_template.project.name, contract_template.name].map(&:parameterize).join("_") filename = [contract_template.project.name, contract_template.name].map(&:parameterize).join("_")
new(url, filename) new(url, "#{filename}.png")
end
def self.build_from_multiple_contract_templates(contract_templates, project)
account = project.account
locale = I18n.locale
host = AppHost.new.domain_with_port
route = [account, project, :contract_templates, contract_template_ids: contract_templates.ids, locale: I18n.locale, host: AppHost.new.domain_with_port]
url = Rails.application.routes.url_helpers.url_for(route)
filename = [project.account.name, project.name].map(&:parameterize).join("_")
new(url, "#{filename}.png")
end end
def initialize(url, filename = "qrcode.png") def initialize(url, filename = "qrcode.png")

View File

@@ -1,5 +1,5 @@
class ReleasableParam class ReleasableParam
TYPES = %w(talent appearance location material acquired_media music medical) TYPES = %w(talent appearance location material acquired_media music medical misc)
def initialize(params) def initialize(params)
@params = params @params = params

View File

@@ -8,7 +8,12 @@ class SampleAppearanceRelease < AppearanceRelease
def default_attrs def default_attrs
{ {
person_address: "Street Address, City, State Zipcode", person_address_street1: "Street Address",
person_address_street2: "St2",
person_address_city: "City",
person_address_state: "State",
person_address_zip: "ZIP",
person_address_country: "Country",
person_first_name: "Some", person_first_name: "Some",
person_last_name: "Person", person_last_name: "Person",
person_phone: "555-555-5555", person_phone: "555-555-5555",

View File

@@ -11,7 +11,17 @@ class TalentRelease < ApplicationRecord
include Taggable include Taggable
include PersonName include PersonName
include GuardianPhotoable include GuardianPhotoable
include SecondGuardianPhotoable
include GuardianName include GuardianName
include SecondGuardianName
include CsvExportable
include Approvable
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",
@@ -35,6 +45,17 @@ class TalentRelease < ApplicationRecord
%w(guardian_address_country country) %w(guardian_address_country country)
] ]
composed_of :guardian_2_address,
class_name: "Address",
mapping: [
%w(guardian_2_address_street1 street1),
%w(guardian_2_address_street2 street2),
%w(guardian_2_address_city city),
%w(guardian_2_address_state state),
%w(guardian_2_address_zip zip),
%w(guardian_2_address_country country)
]
def self.face_photo_acceptable_content_types def self.face_photo_acceptable_content_types
["image/png", "image/jpeg"] ["image/png", "image/jpeg"]
end end
@@ -58,6 +79,7 @@ class TalentRelease < ApplicationRecord
# These validations apply to releases being signed by a minor # These validations apply to releases being signed by a minor
with_options if: :minor? do with_options if: :minor? do
validates :guardian_first_name, :guardian_last_name, presence: true validates :guardian_first_name, :guardian_last_name, presence: true
validates :guardian_email, :guardian_2_email, email: true, allow_blank: true
validates :guardian_phone, presence: true validates :guardian_phone, presence: true
end end
@@ -72,6 +94,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
@@ -81,7 +111,11 @@ class TalentRelease < ApplicationRecord
end end
def uses_edl? def uses_edl?
false true
end
def second_guardian_present?
guardian_2_first_name.present?
end end
def contract_file_name def contract_file_name

View File

@@ -0,0 +1,10 @@
class TaskRequest < ApplicationRecord
belongs_to :project
has_many_attached :files
enum status: [:pending, :completed, :cancelled]
scope :order_by_recent, -> { order(created_at: :desc) }
validates :time_allowed, numericality: { only_integer: true, greater_than_or_equal_to: 2 }, allow_blank: true
end

View File

@@ -12,7 +12,7 @@ class AcquiredMediaReleasePolicy < ApplicationPolicy
end end
def destroy? def destroy?
true user.manager? || user.account_manager?
end end
def tag_multiple? def tag_multiple?
@@ -30,4 +30,12 @@ class AcquiredMediaReleasePolicy < ApplicationPolicy
def download_multiple? def download_multiple?
true true
end end
def review?
user.account_manager?
end
def approve?
review?
end
end end

View File

@@ -16,7 +16,7 @@ class AppearanceReleasePolicy < ReleasePolicy
end end
def destroy? def destroy?
true user.manager? || user.account_manager?
end end
def tag_multiple? def tag_multiple?
@@ -26,4 +26,12 @@ class AppearanceReleasePolicy < ReleasePolicy
def download_multiple? def download_multiple?
true true
end end
def review?
user.account_manager?
end
def approve?
review?
end
end end

View File

@@ -18,4 +18,12 @@ class BroadcastPolicy < ApplicationPolicy
def update? def update?
true true
end end
def destroy_file?
if user.nil? || user.user.nil?
return false
end
user.manager? || user.account_manager?
end
end end

View File

@@ -1,5 +1,9 @@
class ContractPolicy < ApplicationPolicy class ContractPolicy < ApplicationPolicy
def show? def show?
user.manager? || user.account_manager? if record.respond_to?(:medical_release?) && record.medical_release?
user.account_manager?
else
user.manager? || user.account_manager?
end
end end
end end

View File

@@ -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
@@ -21,6 +23,18 @@ class ContractTemplatePolicy < ApplicationPolicy
create? create?
end end
def edit?
record.editable? && create?
end
def update?
edit?
end
def duplicate?
create?
end
def import? def import?
if user.account_manager? if user.account_manager?
record.project.account = user.account record.project.account = user.account

View File

@@ -16,7 +16,7 @@ class LocationReleasePolicy < ReleasePolicy
end end
def destroy? def destroy?
true user.manager? || user.account_manager?
end end
def edit_photos? def edit_photos?
@@ -34,4 +34,16 @@ class LocationReleasePolicy < ReleasePolicy
def download_multiple? def download_multiple?
true true
end end
def review?
user.account_manager?
end
def sign_amendment?
user.manager? || user.account_manager?
end
def approve?
review?
end
end end

View File

@@ -16,7 +16,7 @@ class MaterialReleasePolicy < ReleasePolicy
end end
def destroy? def destroy?
true user.manager? || user.account_manager?
end end
def edit_photos? def edit_photos?
@@ -34,4 +34,12 @@ class MaterialReleasePolicy < ReleasePolicy
def download_multiple? def download_multiple?
true true
end end
def review?
user.account_manager?
end
def approve?
review?
end
end end

View File

@@ -12,7 +12,15 @@ class MedicalReleasePolicy < ReleasePolicy
end end
def destroy? def destroy?
true user.manager? || user.account_manager?
end
def review?
user.account_manager?
end
def approve?
review?
end end
def edit_photos? def edit_photos?
@@ -31,7 +39,11 @@ class MedicalReleasePolicy < ReleasePolicy
true true
end end
def download_single?
user.account_manager?
end
def download_multiple? def download_multiple?
true download_single?
end end
end end

View File

@@ -0,0 +1,49 @@
class MiscReleasePolicy < ReleasePolicy
def create?
true
end
def show?
true
end
def update?
!record.native?
end
def destroy?
user.manager? || user.account_manager?
end
def edit_photos?
true
end
def index?
true
end
def update_photos?
edit_photos?
end
def tag_multiple?
true
end
def download_single?
true
end
def download_multiple?
download_single?
end
def review?
user.account_manager?
end
def approve?
review?
end
end

View File

@@ -12,7 +12,7 @@ class MusicReleasePolicy < ReleasePolicy
end end
def destroy? def destroy?
true user.manager? || user.account_manager?
end end
def tag_multiple? def tag_multiple?
@@ -22,4 +22,12 @@ class MusicReleasePolicy < ReleasePolicy
def download_multiple? def download_multiple?
true true
end end
def review?
user.account_manager?
end
def approve?
review?
end
end end

View File

@@ -36,4 +36,8 @@ class ProjectPolicy < ApplicationPolicy
def show_downloads? def show_downloads?
show? show?
end end
def show_task_results?
show?
end
end end

View File

@@ -12,7 +12,7 @@ class TalentReleasePolicy < ReleasePolicy
end end
def destroy? def destroy?
true user.manager? || user.account_manager?
end end
def edit_photos? def edit_photos?
@@ -34,4 +34,12 @@ class TalentReleasePolicy < ReleasePolicy
def download_multiple? def download_multiple?
true true
end end
def review?
user.account_manager?
end
def approve?
review?
end
end end

View File

@@ -0,0 +1,29 @@
class TaskRequestPolicy < ApplicationPolicy
def index?
true
end
def show?
true
end
def create?
true
end
def destroy?
true
end
def update?
true
end
def cancel?
true
end
def open_deliverable?
true
end
end

View File

@@ -151,6 +151,24 @@ class Analytics
) )
end end
end end
def track_create_task_request(user_agent:, user_ip:)
if analytics_enabled?
identify
track(
{
user_id: user.id,
event: "Task request created",
properties: {
account: account.try(:name),
account_id: account.try(:id),
user_agent: user_agent,
ip: user_ip,
},
}
)
end
end
private private

View File

@@ -1,5 +1,13 @@
<tr id="<%= dom_id(acquired_media_release) %>"> <tr id="<%= dom_id(acquired_media_release) %>">
<td data-behavior="select"><%= check_box_tag "acquired_media_release_ids[]", acquired_media_release.id, false %></td> <td data-behavior="select"><%= check_box_tag "acquired_media_release_ids[]", acquired_media_release.id, false %></td>
<td class="text-center">
<% if acquired_media_release.approved? %>
<% tooltip_user_data = get_approval_data_for_releasable(acquired_media_release) %>
<i class="fa fa-check-circle fa-2x text-success"
data-toggle="tooltip"
title="<%= t '.messages.approved_tooltip', user: tooltip_user_data, timestamp: acquired_media_release.approved_at %>"></i>
<% end %>
</td>
<td> <td>
<%= acquired_media_release.name %> <%= acquired_media_release.name %>
</td> </td>
@@ -35,6 +43,9 @@
<% if policy(Contract).show? && (acquired_media_release.contract.attached? || acquired_media_release.contract_template.present?) %> <% if policy(Contract).show? && (acquired_media_release.contract.attached? || acquired_media_release.contract_template.present?) %>
<%= link_to fa_icon("download fw", text: "Download"), [acquired_media_release, :contracts, format: "pdf"], class: "dropdown-item", target: "_blank" %> <%= link_to fa_icon("download fw", text: "Download"), [acquired_media_release, :contracts, format: "pdf"], class: "dropdown-item", target: "_blank" %>
<% end %> <% end %>
<% if policy(AcquiredMediaRelease).review? %>
<%= link_to fa_icon("search fw", text: t('.actions.review')), new_acquired_media_release_approvals_path(acquired_media_release), class: "dropdown-item" %>
<% end %>
<% if policy(acquired_media_release).edit? %> <% if policy(acquired_media_release).edit? %>
<%= link_to fa_icon("pencil fw", text: "Edit"), [:edit, acquired_media_release], class: "dropdown-item" %> <%= link_to fa_icon("pencil fw", text: "Edit"), [:edit, acquired_media_release], class: "dropdown-item" %>
<% end %> <% end %>

View File

@@ -1,6 +1,10 @@
<%= errors_summary_for acquired_media_release %> <%= errors_summary_for acquired_media_release %>
<%= bootstrap_form_with model: model, local: true do |form| %> <%= bootstrap_form_with model: model, local: true do |form| %>
<%= field_set_tag content_tag(:span, t(".acquired_media_details.heading"), class: "h6 text-muted text-uppercase") do %> <%= field_set_tag content_tag(:span, t(".acquired_media_details.heading"), class: "h6 text-muted text-uppercase") do %>
<%= form.form_group :minor do %>
<%= form.check_box :minor, label: t("helpers.label.talent_release.minor"), data: { target: "[data-ujs-target=guardian-fields]", toggle: "collapse" } %>
<% end %>
<div class="form-row"> <div class="form-row">
<%= form.text_field :name, required: true, wrapper_class: "col-12" %> <%= form.text_field :name, required: true, wrapper_class: "col-12" %>
</div> </div>
@@ -9,6 +13,28 @@
<%= form.check_box :categories, { multiple: true, label: category }, category, false %> <%= form.check_box :categories, { multiple: true, label: category }, category, false %>
<% end %> <% end %>
<% end %> <% end %>
<div class="<%= class_string("collapse" => !acquired_media_release.minor?) %>" data-ujs-target="guardian-fields">
<%= card_field_set_tag t(".guardian_info.heading") do %>
<div class="form-row">
<%= form.text_field :guardian_first_name, required: acquired_media_release.minor?, wrapper_class: "col-sm-3" %>
<%= form.text_field :guardian_last_name, required: acquired_media_release.minor?, wrapper_class: "col-sm-3" %>
<%= form.phone_field :guardian_phone, wrapper_class: "col-sm-6" %>
<%= form.text_field :guardian_email, wrapper_class: "col-sm-6" %>
</div>
<%= render "shared/address_fields", form: form, subject: "guardian" %>
<% end %>
<%= card_field_set_tag t(".guardian_2_info.heading") do %>
<div class="form-row">
<%= form.text_field :guardian_2_first_name, wrapper_class: "col-sm-3" %>
<%= form.text_field :guardian_2_last_name, wrapper_class: "col-sm-3" %>
<%= form.phone_field :guardian_2_phone, wrapper_class: "col-sm-6" %>
<%= form.text_field :guardian_2_email, wrapper_class: "col-sm-6" %>
</div>
<%= render "shared/address_fields", form: form, subject: "guardian_2" %>
<% end %>
</div>
<% end %> <% end %>
<hr> <hr>
@@ -19,6 +45,44 @@
<strong>For optimal accuracy, please ensure video file names and photo file names match the source file name in the editing sequence.</strong> <strong>For optimal accuracy, please ensure video file names and photo file names match the source file name in the editing sequence.</strong>
</div> </div>
<%= render "shared/file_infos_dropzone", form: form, releasable: acquired_media_release %> <%= render "shared/file_infos_dropzone", form: form, releasable: acquired_media_release %>
<div class="<%= class_string("collapse" => !acquired_media_release.minor?) %>" data-ujs-target="guardian-fields">
<br>
<div class="text-left">
<p><%= t(".photos.guardian_photo.heading") %></p>
<div id="guardian-photo-preview" class="d-inline-block mb-2" data-behavior="guardian-photo-preview" data-file-input="[data-ujs-target=guardian-photo-input]">
<div class="align-items-center d-flex photo-preview img-thumbnail justify-content-center">
<span>No photo yet</span>
</div>
</div>
<% if acquired_media_release.guardian_photo.attached? %>
<%= javascript_tag nonce: true do %>
App.PhotoPreview.set("#guardian-photo-preview", "<%= url_for(acquired_media_release.guardian_photo.variant(auto_orient: true, resize: '200x200')) %>");
<% end %>
<% end %>
<div class="d-inline-block">
<%= form.hidden_field :guardian_photo, value: form.object.guardian_photo.signed_id if acquired_media_release.guardian_photo.attached?%>
<%= form.file_field :guardian_photo, hide_label: true, data: { ujs_target: "guardian-photo-input" }, help: "PNG or JPG only", accept: acquired_media_release.class.face_photo_acceptable_content_types.join(",") %>
</div>
<p><%= t(".photos.guardian_2_photo.heading") %></p>
<div id="guardian-2-photo-preview" class="d-inline-block mb-2" data-behavior="guardian-photo-preview" data-file-input="[data-ujs-target=guardian-2-photo-input]">
<div class="align-items-center d-flex photo-preview img-thumbnail justify-content-center">
<span>No photo yet</span>
</div>
</div>
<% if acquired_media_release.guardian_2_photo.attached? %>
<%= javascript_tag nonce: true do %>
App.PhotoPreview.set("#guardian-2-photo-preview", "<%= url_for(acquired_media_release.guardian_2_photo.variant(auto_orient: true, resize: '200x200')) %>");
<% end %>
<% end %>
<div class="d-inline-block">
<%= form.hidden_field :guardian_2_photo, value: form.object.guardian_2_photo.signed_id if acquired_media_release.guardian_2_photo.attached?%>
<%= form.file_field :guardian_2_photo, hide_label: true, data: { ujs_target: "guardian-2-photo-input" }, help: "PNG or JPG only", accept: acquired_media_release.class.face_photo_acceptable_content_types.join(",") %>
</div>
</div>
<hr>
</div>
<% end %> <% end %>
<hr> <hr>

View File

@@ -26,6 +26,7 @@
<thead class="thead-light"> <thead class="thead-light">
<tr> <tr>
<th data-behavior="all-selectable"><%= check_box_tag "acquired_media_release_ids[]", false, false %></th> <th data-behavior="all-selectable"><%= check_box_tag "acquired_media_release_ids[]", false, false %></th>
<th><%= t '.table_headers.approved'%></th>
<th><%= AcquiredMediaRelease.human_attribute_name(:name) %></th> <th><%= AcquiredMediaRelease.human_attribute_name(:name) %></th>
<th><%= t(".table_headers.file_infos_count") %></th> <th><%= t(".table_headers.file_infos_count") %></th>
<th><%= t(".table_headers.notes") %></th> <th><%= t(".table_headers.notes") %></th>

View File

@@ -7,6 +7,9 @@
<li class="nav-item"> <li class="nav-item">
<%= link_to fa_icon("users fw", text: "Users"), [:admin, :users], class: class_string("nav-link", "active" => controller_name == "users") %> <%= link_to fa_icon("users fw", text: "Users"), [:admin, :users], class: class_string("nav-link", "active" => controller_name == "users") %>
</li> </li>
<li class="nav-item">
<%= link_to fa_icon("tasks fw", text: "Task Requests"), [:admin, :task_requests], class: class_string("nav-link", "active" => controller_name == "task_requests") %>
</li>
<li class="nav-item"> <li class="nav-item">
<%= link_to fa_icon("bug fw", text: "Errors"), "https://sentry.io/bigmedia/", class: "nav-link", target: :_blank %> <%= link_to fa_icon("bug fw", text: "Errors"), "https://sentry.io/bigmedia/", class: "nav-link", target: :_blank %>
</li> </li>

View File

@@ -0,0 +1,13 @@
<%= errors_summary_for task_request %>
<%= bootstrap_form_with model: model, local: true do |form| %>
<%= form.select :status, options_for_select(TaskRequest.statuses.except(:cancelled).keys, task_request.status), {}, class: "form-control custom-select" %>
<%= form.text_field :deliverable_url %>
<div class="row align-items-center text-center mt-4">
<%= link_to t("shared.cancel"), [:admin, :task_requests], class: "col-3 text-reset" %>
<div class="col-9">
<%= form.submit class: class_string("btn btn-block", ["btn-success", "btn-primary"] => task_request.new_record?), data: { disable_with: t("shared.disable_with") } %>
</div>
</div>
<% end %>

Some files were not shown because too many files have changed in this diff Show More