diff --git a/app/controllers/projects_controller.rb b/app/controllers/projects_controller.rb
index ad3fefa..c02708d 100644
--- a/app/controllers/projects_controller.rb
+++ b/app/controllers/projects_controller.rb
@@ -60,7 +60,7 @@ class ProjectsController < ApplicationController
end
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
def project_params_with_current_account
diff --git a/app/models/account.rb b/app/models/account.rb
index 5c82e51..c4513b6 100644
--- a/app/models/account.rb
+++ b/app/models/account.rb
@@ -56,6 +56,7 @@ class Account < ApplicationRecord
Broadcast.where(project: projects),
ZoomMeeting.where(project: projects),
MedicalRelease.where(project: projects),
+ MiscRelease.where(project: projects),
MatchingRequest.where(project: projects),
self
])).sum(:byte_size).to_f
diff --git a/app/models/contract_template.rb b/app/models/contract_template.rb
index b492be1..6b213a6 100644
--- a/app/models/contract_template.rb
+++ b/app/models/contract_template.rb
@@ -14,6 +14,7 @@ class ContractTemplate < ApplicationRecord
has_many :location_releases, dependent: :restrict_with_error
has_many :material_releases, dependent: :restrict_with_error
has_many :medical_releases, dependent: :restrict_with_error
+ has_many :misc_releases, dependent: :restrict_with_error
monetize :fee_cents
has_rich_text :body
diff --git a/app/models/misc_release.rb b/app/models/misc_release.rb
new file mode 100644
index 0000000..61ee820
--- /dev/null
+++ b/app/models/misc_release.rb
@@ -0,0 +1,85 @@
+class MiscRelease < ApplicationRecord
+ include Contractable
+ include Notable
+ include Photoable
+ include Releasable
+ include Searchable
+ include Signable
+ include Syncable
+ include PersonName
+ include GuardianName
+
+ 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
diff --git a/app/models/project.rb b/app/models/project.rb
index e37f081..d972194 100644
--- a/app/models/project.rb
+++ b/app/models/project.rb
@@ -3,8 +3,8 @@ class Project < ApplicationRecord
include Filterable
include Syncable
- SIGNABLE_RELEASE_TYPES = %w(talent appearance acquired_media location material medical)
- AVAILABLE_RELEASE_TYPES = %w(appearance location material acquired_media talent music 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 misc)
belongs_to :account
has_many :acquired_media_releases, dependent: :destroy
@@ -14,6 +14,7 @@ class Project < ApplicationRecord
has_many :music_releases, dependent: :destroy
has_many :talent_releases, dependent: :destroy
has_many :medical_releases, dependent: :destroy
+ has_many :misc_releases, dependent: :destroy
has_many :videos, dependent: :destroy
has_many :imports, dependent: :destroy
has_many :contract_templates, dependent: :destroy
@@ -35,6 +36,7 @@ class Project < ApplicationRecord
music_release: false,
talent_release: false,
medical_release: false,
+ misc_release: false,
video_analysis: false,
}
end
@@ -68,6 +70,7 @@ class Project < ApplicationRecord
music_release: true,
talent_release: true,
medical_release: true,
+ misc_release: true,
video_analysis: true,
}
when "nat_geo"
@@ -80,6 +83,7 @@ class Project < ApplicationRecord
music_release: true,
talent_release: true,
medical_release: true,
+ misc_release: true,
video_analysis: true,
}
else
diff --git a/app/views/contract_templates/_form.html.erb b/app/views/contract_templates/_form.html.erb
index dc74784..18bdc7e 100644
--- a/app/views/contract_templates/_form.html.erb
+++ b/app/views/contract_templates/_form.html.erb
@@ -2,7 +2,7 @@
<%= field_set_tag content_tag(:span, t(".release_info.heading"), class: "h6 text-muted text-uppercase") do %>
<%= form.text_field :name, wrapper_class: "col-sm-6" %>
- <%= form.select :release_type, options_for_release_type_select(project, @release_type), { wrapper_class: "col-sm-6" }, data: { toggle: "collapse-select", target_show_values_mapping: { "#guardian_clause": %w(appearance talent), "#fee_field": %w(appearance talent location material acquired_media), "#exploitable_rights_fields": %w(appearance talent location material acquired_media), "#custom_fields": %w(medical) } }, class: "form-control custom-select" %>
+ <%= form.select :release_type, options_for_release_type_select(project, @release_type), { wrapper_class: "col-sm-6" }, data: { toggle: "collapse-select", target_show_values_mapping: { "#guardian_clause": %w(appearance talent misc), "#fee_field": %w(appearance talent location material acquired_media), "#exploitable_rights_fields": %w(appearance talent location material acquired_media), "#custom_fields": %w(medical) } }, class: "form-control custom-select" %>
<%= form.number_field :fee, min:"0", max:"99999999", step: "0.01", prepend: "$", help: "Leave at $0.00 for no-fee", wrapper_class: "col-sm-6" %>
diff --git a/config/locales/en.yml b/config/locales/en.yml
index 1ee2770..65c27ab 100644
--- a/config/locales/en.yml
+++ b/config/locales/en.yml
@@ -751,6 +751,7 @@ en:
location_release: Location Releases
material_release: Material Releases (Products / Logos)
medical_release: Medical Releases
+ misc_release: Misc Releases
music_release: Music Releases (Original Music)
talent_release: Talent Releases
index:
@@ -778,6 +779,7 @@ en:
location_release: Location Releases (%{count})
material_release: Material Releases (%{count})
medical_release: Medical Releases (%{count})
+ misc_release: Misc Releases (%{count})
music_release: Music Releases (%{count})
report: Reports
talent_release: Talent Releases (%{count})
diff --git a/config/routes.rb b/config/routes.rb
index 824f901..50db726 100644
--- a/config/routes.rb
+++ b/config/routes.rb
@@ -54,6 +54,7 @@ Rails.application.routes.draw do
resources :music_releases, except: [:show], concerns: [:contractable, :notable]
resources :talent_releases, except: [:show], concerns: [:contractable, :notable, :photoable]
resources :medical_releases, except: [:show], concerns: [:contractable, :notable, :photoable]
+ resources :misc_releases, except: [:show], concerns: [:contractable, :notable, :photoable]
resources :contract_templates, only: [:index, :new, :create, :destroy] do
resource :qr_codes, only: [:show], controller: "contract_templates/qr_codes"
resource :blank_contracts, only: [:show, :new, :create], controller: "contract_templates/blank_contracts"
@@ -119,6 +120,7 @@ Rails.application.routes.draw do
resources :location_releases, only: [:new, :create]
resources :material_releases, only: [:new, :create]
resources :medical_releases, only: [:new, :create]
+ resources :misc_releases, only: [:new, :create]
end
end
end
@@ -128,7 +130,7 @@ Rails.application.routes.draw do
end
RELEASES = [:acquired_media_releases, :appearance_releases, :talent_releases, :material_releases, :location_releases]
- ALL_RELEASES = RELEASES + [:music_releases, :medical_releases]
+ ALL_RELEASES = RELEASES + [:music_releases, :medical_releases, :misc_releases]
ALL_RELEASES.each do |release|
resources release, only: [], concerns: :taggable
diff --git a/db/migrate/20200619085823_create_misc_releases.rb b/db/migrate/20200619085823_create_misc_releases.rb
new file mode 100644
index 0000000..9bf0f52
--- /dev/null
+++ b/db/migrate/20200619085823_create_misc_releases.rb
@@ -0,0 +1,34 @@
+class CreateMiscReleases < ActiveRecord::Migration[6.0]
+ def change
+ create_table :misc_releases do |t|
+ t.belongs_to :project, foreign_key: true
+ t.belongs_to :contract_template, foreign_key: true
+ t.string :person_first_name
+ t.string :person_last_name
+ t.string :person_address_street1
+ t.string :person_address_street2
+ t.string :person_address_city
+ t.string :person_address_state
+ t.string :person_address_zip
+ t.string :person_address_country
+ t.string :person_phone
+ t.string :person_email
+ t.string :guardian_first_name
+ t.string :guardian_last_name
+ t.string :guardian_address_street1
+ t.string :guardian_address_street2
+ t.string :guardian_address_city
+ t.string :guardian_address_state
+ t.string :guardian_address_zip
+ t.string :guardian_address_country
+ t.string :guardian_phone
+ t.string :guardian_email
+ t.string :locale
+ t.text :notes
+ t.datetime :signed_at
+ t.boolean :minor, default: false
+
+ t.timestamps
+ end
+ end
+end
diff --git a/db/structure.sql b/db/structure.sql
index d3f8386..3ad5cad 100644
--- a/db/structure.sql
+++ b/db/structure.sql
@@ -1051,6 +1051,62 @@ CREATE SEQUENCE public.medical_releases_id_seq
ALTER SEQUENCE public.medical_releases_id_seq OWNED BY public.medical_releases.id;
+--
+-- Name: misc_releases; Type: TABLE; Schema: public; Owner: -
+--
+
+CREATE TABLE public.misc_releases (
+ id bigint NOT NULL,
+ project_id bigint,
+ contract_template_id bigint,
+ person_first_name character varying,
+ person_last_name character varying,
+ person_address_street1 character varying,
+ person_address_street2 character varying,
+ person_address_city character varying,
+ person_address_state character varying,
+ person_address_zip character varying,
+ person_address_country character varying,
+ person_phone character varying,
+ person_email character varying,
+ guardian_first_name character varying,
+ guardian_last_name character varying,
+ guardian_address_street1 character varying,
+ guardian_address_street2 character varying,
+ guardian_address_city character varying,
+ guardian_address_state character varying,
+ guardian_address_zip character varying,
+ guardian_address_country character varying,
+ guardian_phone character varying,
+ guardian_email character varying,
+ locale character varying,
+ notes text,
+ signed_at timestamp without time zone,
+ minor boolean DEFAULT false,
+ created_at timestamp(6) without time zone NOT NULL,
+ updated_at timestamp(6) without time zone NOT NULL
+);
+
+
+--
+-- Name: misc_releases_id_seq; Type: SEQUENCE; Schema: public; Owner: -
+--
+
+CREATE SEQUENCE public.misc_releases_id_seq
+ START WITH 1
+ INCREMENT BY 1
+ NO MINVALUE
+ NO MAXVALUE
+ CACHE 1;
+
+
+--
+-- Name: misc_releases_id_seq; Type: SEQUENCE OWNED BY; Schema: public; Owner: -
+--
+
+ALTER SEQUENCE public.misc_releases_id_seq OWNED BY public.misc_releases.id;
+
+
--
-- Name: music_releases; Type: TABLE; Schema: public; Owner: -
--
@@ -1904,6 +1960,13 @@ ALTER TABLE ONLY public.material_releases ALTER COLUMN id SET DEFAULT nextval('p
ALTER TABLE ONLY public.medical_releases ALTER COLUMN id SET DEFAULT nextval('public.medical_releases_id_seq'::regclass);
+--
+-- Name: misc_releases id; Type: DEFAULT; Schema: public; Owner: -
+--
+
+ALTER TABLE ONLY public.misc_releases ALTER COLUMN id SET DEFAULT nextval('public.misc_releases_id_seq'::regclass);
+
+
--
-- Name: music_releases id; Type: DEFAULT; Schema: public; Owner: -
--
@@ -2222,6 +2285,14 @@ ALTER TABLE ONLY public.medical_releases
ADD CONSTRAINT medical_releases_pkey PRIMARY KEY (id);
+--
+-- Name: misc_releases misc_releases_pkey; Type: CONSTRAINT; Schema: public; Owner: -
+--
+
+ALTER TABLE ONLY public.misc_releases
+ ADD CONSTRAINT misc_releases_pkey PRIMARY KEY (id);
+
+
--
-- Name: music_releases music_releases_pkey; Type: CONSTRAINT; Schema: public; Owner: -
--
@@ -2738,6 +2809,20 @@ CREATE INDEX index_medical_releases_on_contract_template_id ON public.medical_re
CREATE INDEX index_medical_releases_on_project_id ON public.medical_releases USING btree (project_id);
+--
+-- Name: index_misc_releases_on_contract_template_id; Type: INDEX; Schema: public; Owner: -
+--
+
+CREATE INDEX index_misc_releases_on_contract_template_id ON public.misc_releases USING btree (contract_template_id);
+
+
+--
+-- Name: index_misc_releases_on_project_id; Type: INDEX; Schema: public; Owner: -
+--
+
+CREATE INDEX index_misc_releases_on_project_id ON public.misc_releases USING btree (project_id);
+
+
--
-- Name: index_music_releases_on_applicable_medium_id; Type: INDEX; Schema: public; Owner: -
--
@@ -3039,6 +3124,14 @@ CREATE UNIQUE INDEX taggings_idx ON public.taggings USING btree (tag_id, taggabl
CREATE INDEX taggings_idy ON public.taggings USING btree (taggable_id, taggable_type, tagger_id, context);
+--
+-- Name: misc_releases fk_rails_0222652fcd; Type: FK CONSTRAINT; Schema: public; Owner: -
+--
+
+ALTER TABLE ONLY public.misc_releases
+ ADD CONSTRAINT fk_rails_0222652fcd FOREIGN KEY (project_id) REFERENCES public.projects(id);
+
+
--
-- Name: unreleased_appearances fk_rails_0393a349dd; Type: FK CONSTRAINT; Schema: public; Owner: -
--
@@ -3447,6 +3540,14 @@ ALTER TABLE ONLY public.active_storage_attachments
ADD CONSTRAINT fk_rails_c3b3935057 FOREIGN KEY (blob_id) REFERENCES public.active_storage_blobs(id);
+--
+-- Name: misc_releases fk_rails_c664291b9b; Type: FK CONSTRAINT; Schema: public; Owner: -
+--
+
+ALTER TABLE ONLY public.misc_releases
+ ADD CONSTRAINT fk_rails_c664291b9b FOREIGN KEY (contract_template_id) REFERENCES public.contract_templates(id);
+
+
--
-- Name: location_releases fk_rails_c7458d662e; Type: FK CONSTRAINT; Schema: public; Owner: -
--
@@ -3691,6 +3792,7 @@ INSERT INTO "schema_migrations" (version) VALUES
('20200615131722'),
('20200615133602'),
('20200616124214'),
-('20200619081446');
+('20200619081446'),
+('20200619085823');
diff --git a/lib/tasks/dev.rake b/lib/tasks/dev.rake
index dbeedb6..432f383 100644
--- a/lib/tasks/dev.rake
+++ b/lib/tasks/dev.rake
@@ -33,6 +33,8 @@ if Rails.env.development? || Rails.env.test? || Rails.env.review?
material_release: true,
music_release: true,
talent_release: true,
+ medical_release: true,
+ misc_release: true,
video_analysis: true,
})
diff --git a/spec/factories/contract_templates.rb b/spec/factories/contract_templates.rb
index caf8088..8d90846 100644
--- a/spec/factories/contract_templates.rb
+++ b/spec/factories/contract_templates.rb
@@ -28,6 +28,10 @@ FactoryBot.define do
release_type "material"
end
+ factory :misc_release_contract_template do
+ release_type "misc"
+ end
+
factory :location_release_contract_template do
release_type "location"
end
diff --git a/spec/factories/misc_releases.rb b/spec/factories/misc_releases.rb
new file mode 100644
index 0000000..2a6003f
--- /dev/null
+++ b/spec/factories/misc_releases.rb
@@ -0,0 +1,47 @@
+FactoryBot.define do
+ factory :misc_release do
+ association :project
+
+ person_first_name "Jane"
+ person_last_name "Doe"
+
+ photos [Rack::Test::UploadedFile.new(Rails.root.join("spec", "fixtures", "files", "person_photo.png"), "image/png")]
+
+ trait :native do
+ person_phone "123-555-6789"
+
+ signature do
+ path = Rails.root.join("spec", "fixtures", "files", "signature.png")
+ Rack::Test::UploadedFile.new(path, "image/png")
+ end
+ end
+
+ trait :minor do
+ minor true
+ guardian_first_name "Jamie"
+ guardian_last_name "Doe"
+ guardian_phone "123-555-1234"
+ end
+
+ factory :misc_release_with_contract_template do
+ after(:build) do |misc_release, _|
+ misc_release.contract_template = build(:misc_release_contract_template)
+ end
+ end
+
+ factory :misc_release_with_contract_template_and_photos do
+ after(:build) do |misc_release, _|
+ misc_release.contract_template = build(:misc_release_contract_template)
+ path = Rails.root.join("spec", "fixtures", "files", "person_photo.png")
+ misc_release.photos.attach Rack::Test::UploadedFile.new(path, "image/png")
+ end
+ end
+
+ factory :misc_release_with_photo do
+ after(:build) do |misc_release, _|
+ path = Rails.root.join("spec", "fixtures", "files", "person_photo.png")
+ misc_release.photos.attach Rack::Test::UploadedFile.new(path, "image/png")
+ end
+ end
+ end
+end
diff --git a/spec/models/account_spec.rb b/spec/models/account_spec.rb
index 8147964..29e8eeb 100644
--- a/spec/models/account_spec.rb
+++ b/spec/models/account_spec.rb
@@ -132,6 +132,7 @@ RSpec.describe Account do
Account,
ZoomMeeting,
MedicalRelease,
+ MiscRelease,
MatchingRequest
]
Rails.application.eager_load!
diff --git a/spec/models/contract_template_spec.rb b/spec/models/contract_template_spec.rb
index 3e801e9..834ac9a 100644
--- a/spec/models/contract_template_spec.rb
+++ b/spec/models/contract_template_spec.rb
@@ -14,6 +14,7 @@ describe ContractTemplate do
it { is_expected.to have_many(:location_releases).dependent(:restrict_with_error) }
it { is_expected.to have_many(:material_releases).dependent(:restrict_with_error) }
it { is_expected.to have_many(:medical_releases).dependent(:restrict_with_error) }
+ it { is_expected.to have_many(:misc_releases).dependent(:restrict_with_error) }
end
describe 'validations' do
diff --git a/spec/models/misc_release_spec.rb b/spec/models/misc_release_spec.rb
new file mode 100644
index 0000000..ce68b16
--- /dev/null
+++ b/spec/models/misc_release_spec.rb
@@ -0,0 +1,53 @@
+require 'rails_helper'
+
+RSpec.describe MiscRelease, type: :model do
+ it_behaves_like "a contractable"
+ it_behaves_like "a notable"
+ it_behaves_like "a photoable"
+ it_behaves_like "a releasable"
+
+ describe "validations" do
+ it { is_expected.to validate_presence_of(:person_first_name) }
+ it { is_expected.to validate_presence_of(:person_last_name) }
+
+ context "for #person_email" do
+ it { is_expected.to allow_value("test@test.com", nil).for(:person_email) }
+ it { is_expected.not_to allow_values("foo", "test@foo", "N/A").for(:person_email) }
+ end
+
+ context "for native releases" do
+ it { is_expected.to validate_attachment_of(:signature).on(:native) }
+ end
+
+ context "for non-native releases" do
+ it { is_expected.to validate_attachment_of(:contract).on(:non_native) }
+ end
+ end
+
+ describe "attachments" do
+ it { is_expected.to respond_to(:signature) }
+ end
+
+ describe "#uses_edl?" do
+ it { is_expected.not_to be_uses_edl }
+ end
+
+ describe "#contract_file_name" do
+ it "includes project name, signed at date, release type, release number and person name" do
+ release = create(:misc_release_with_contract_template, id: 100, signed_at: Date.new(2020, 2, 10), person_first_name: "John", person_last_name: "Doe")
+
+ expect(release.contract_file_name).to eq("my-video-project_misc_2020.02.10_1_doe-john")
+ end
+
+ context "when signed at is nil" do
+ it "uses the created at date" do
+ release = create(:misc_release_with_contract_template,
+ signed_at: nil,
+ created_at: DateTime.new(2020, 2, 10, 12, 0, 0),
+ person_first_name: "John", person_last_name: "Doe")
+
+ expect(release.contract_file_name).to eq("my-video-project_misc_2020.02.10_1_doe-john")
+ end
+ end
+ end
+end
diff --git a/spec/models/project_spec.rb b/spec/models/project_spec.rb
index 9230153..4210321 100644
--- a/spec/models/project_spec.rb
+++ b/spec/models/project_spec.rb
@@ -10,6 +10,7 @@ RSpec.describe Project, type: :model do
it { is_expected.to have_many(:music_releases).dependent(:destroy) }
it { is_expected.to have_many(:talent_releases).dependent(:destroy) }
it { is_expected.to have_many(:medical_releases).dependent(:destroy) }
+ it { is_expected.to have_many(:misc_releases).dependent(:destroy) }
it { is_expected.to have_many(:videos).dependent(:destroy) }
it { is_expected.to have_many(:contract_templates).dependent(:destroy) }
it { is_expected.to have_many(:project_memberships).dependent(:destroy) }