Skip to content

Commit e1966b1

Browse files
TWM-524 new sales rep region needed (#1475)
* add new region model to apply to agencies and people * add new rights_designation value * update deprecating enums for rails 8 compatibility * update tests/code for passing * update migration for text correction * switch to new region_id rather than name for grouping (belongs to/has many) * rubocop corrections
1 parent b62bddd commit e1966b1

23 files changed

+592
-70
lines changed
Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,6 @@
1+
# frozen_string_literal: true
2+
3+
module Admin
4+
class RegionsController < Admin::ApplicationController
5+
end
6+
end

app/controllers/agencies_controller.rb

Lines changed: 10 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -3,10 +3,15 @@
33
class AgenciesController < ApplicationController
44
def index
55
@default_agency = Agency.find_by(region: "All Other Territories")
6-
@agencies = Agency.where.not(region: "All Other Territories")
7-
.group_by(&:region)
8-
.sort
9-
.map { |region, agencies| [region, agencies] }
10-
.sort
6+
scoped = Agency.where.not(region: "All Other Territories").includes(:region_ref)
7+
grouped = scoped.group_by do |agency|
8+
record = agency.region_record
9+
designation = record&.rights_designation || agency.send(:parsed_rights_designation)
10+
name = record&.name || agency.region
11+
[name, designation]
12+
end
13+
14+
@agencies = grouped.sort_by { |(name, designation), _| [name.to_s, designation.to_s] }
15+
.map { |(name, _designation), agencies| [name, agencies] }
1116
end
1217
end

app/dashboards/agency_dashboard.rb

Lines changed: 7 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -19,7 +19,10 @@ class AgencyDashboard < Administrate::BaseDashboard
1919
fax: Field::String,
2020
email: Field::String,
2121
website: Field::String,
22-
region: Field::Select.with_options(collection: I18n.t("tupress.admin.collections.agencies.regions")),
22+
region_ref: Field::BelongsTo.with_options(
23+
class_name: "Region",
24+
order: "name ASC"
25+
),
2326
created_at: Field::DateTime,
2427
updated_at: Field::DateTime
2528
}.freeze
@@ -31,7 +34,7 @@ class AgencyDashboard < Administrate::BaseDashboard
3134
# Feel free to add, remove, or rearrange items.
3235
COLLECTION_ATTRIBUTES = %i[
3336
title
34-
region
37+
region_ref
3538
contact
3639
].freeze
3740

@@ -45,7 +48,7 @@ class AgencyDashboard < Administrate::BaseDashboard
4548
fax
4649
email
4750
website
48-
region
51+
region_ref
4952
].freeze
5053

5154
# FORM_ATTRIBUTES
@@ -54,7 +57,7 @@ class AgencyDashboard < Administrate::BaseDashboard
5457
FORM_ATTRIBUTES = %i[
5558
title
5659
slug
57-
region
60+
region_ref
5861
contact
5962
address
6063
phone

app/dashboards/person_dashboard.rb

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -22,7 +22,10 @@ class PersonDashboard < Administrate::BaseDashboard
2222
coverage: Field::String,
2323
company: Field::String,
2424
region: Field::Select.with_options(
25-
collection: I18n.t("tupress.admin.people.regions")
25+
collection: -> {
26+
Region.order(:name, :rights_designation).map { |r| [r.display_name, r.name] }
27+
},
28+
include_blank: true
2629
),
2730
website: Field::String,
2831
created_at: Field::DateTime,

app/dashboards/region_dashboard.rb

Lines changed: 79 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,79 @@
1+
# frozen_string_literal: true
2+
3+
require "administrate/base_dashboard"
4+
5+
class RegionDashboard < Administrate::BaseDashboard
6+
# ATTRIBUTE_TYPES
7+
# a hash that describes the type of each of the model's fields.
8+
#
9+
# Each different type represents an Administrate::Field object,
10+
# which determines how the attribute is displayed
11+
# on pages throughout the dashboard.
12+
ATTRIBUTE_TYPES = {
13+
id: Field::Number,
14+
name: Field::String,
15+
display_name: Field::String,
16+
slug: Field::String,
17+
description: Field::Text,
18+
rights_designation: Field::Select.with_options(
19+
collection: Region.rights_designations.keys.map { |k| [k.titleize, k] }
20+
),
21+
agencies: Field::HasMany,
22+
people: Field::HasMany,
23+
created_at: Field::DateTime,
24+
updated_at: Field::DateTime
25+
}.freeze
26+
27+
# COLLECTION_ATTRIBUTES
28+
# an array of attributes that will be displayed on the model's index page.
29+
#
30+
# By default, it's limited to four items to reduce clutter on index pages.
31+
# Feel free to add, remove, or rearrange items.
32+
COLLECTION_ATTRIBUTES = %i[
33+
display_name
34+
description
35+
agencies
36+
].freeze
37+
38+
# SHOW_PAGE_ATTRIBUTES
39+
# an array of attributes that will be displayed on the model's show page.
40+
SHOW_PAGE_ATTRIBUTES = %i[
41+
display_name
42+
slug
43+
description
44+
rights_designation
45+
agencies
46+
people
47+
created_at
48+
updated_at
49+
].freeze
50+
51+
# FORM_ATTRIBUTES
52+
# an array of attributes that will be displayed
53+
# on the model's form (`new` and `edit`) pages.
54+
FORM_ATTRIBUTES = %i[
55+
name
56+
slug
57+
description
58+
rights_designation
59+
].freeze
60+
61+
# COLLECTION_FILTERS
62+
# a hash that defines filters that can be used while searching via the search
63+
# field of the dashboard.
64+
#
65+
# For example to add an option to search for open resources by typing "open:"
66+
# in the search field:
67+
#
68+
# COLLECTION_FILTERS = {
69+
# open: ->(resources) { resources.where(open: true) }
70+
# }.freeze
71+
COLLECTION_FILTERS = {}.freeze
72+
73+
# Overwrite this method to customize how regions are displayed
74+
# across all pages of the admin dashboard.
75+
#
76+
def display_resource(region)
77+
region.display_name
78+
end
79+
end

app/helpers/agencies_helper.rb

Lines changed: 8 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -1,12 +1,13 @@
11
# frozen_string_literal: true
22

33
module AgenciesHelper
4-
def rights_coverage(region)
5-
case region
6-
when "Turkey", "Spanish & Portuguese languages, World"
7-
"Exclusive Rights"
8-
else
9-
"Non-exclusive Rights"
10-
end
4+
def rights_coverage(agency)
5+
return if agency.blank?
6+
7+
text = agency.rights_type.to_s
8+
return if text.blank?
9+
10+
clean_text = text.gsub(/\A\((.*)\)\z/, '\1').strip
11+
content_tag(:span, content_tag(:em, clean_text), style: "font-size:65%;")
1112
end
1213
end

app/models/agency.rb

Lines changed: 41 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,48 @@
33
class Agency < ApplicationRecord
44
include Friendable
55

6+
belongs_to :region_ref, class_name: "Region", foreign_key: :region_id, optional: true, inverse_of: :agencies
7+
68
validates :title, :region, presence: true
79

810
has_rich_text :address
11+
12+
before_validation :sync_region_from_ref
13+
14+
scope :by_region, ->(region) { where(region: region) }
15+
16+
def region_record
17+
return region_ref if region_ref.present?
18+
return nil if region.blank?
19+
20+
@region_record ||= begin
21+
normalized = region.to_s.sub(/\s*\(.*\)\s*\z/, "").strip
22+
base_name = normalized.gsub(/\b(world\s+exclusive|non[-\s]?exclusive|exclusive)\b(\s+rights?)?/i, "").strip
23+
scope = Region.where(name: [normalized, base_name].uniq)
24+
25+
designation = parsed_rights_designation
26+
scoped_scope = designation ? scope.where(rights_designation: Region.rights_designations[designation]) : scope
27+
28+
scoped_scope.first || scope.first
29+
end
30+
end
31+
32+
def rights_type
33+
region_record&.rights_type
34+
end
35+
36+
private
37+
38+
def sync_region_from_ref
39+
self.region = region_ref.name if region_ref.present?
40+
end
41+
42+
def parsed_rights_designation
43+
label = region.to_s.downcase
44+
return :world_exclusive if label.include?("world exclusive")
45+
return :non_exclusive if label.include?("non-exclusive") || label.include?("non exclusive")
46+
return :exclusive if label.include?("exclusive")
47+
return :unspecified if label.include?("unspecified")
48+
nil
49+
end
950
end

app/models/concerns/friendable.rb

Lines changed: 35 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -8,32 +8,41 @@ module Friendable
88
end
99

1010
def title_and_sequence
11-
case self.class
12-
when "Review"
13-
slug = [cleanup(book.sort_title)]
14-
when "Book"
15-
slug = [cleanup(sort_title)]
16-
else
17-
slug = title.parameterize if title.present?
18-
end
11+
base_slug =
12+
case self
13+
when Review
14+
cleanup(book.sort_title)
15+
when Book
16+
cleanup(sort_title)
17+
else
18+
title&.parameterize
19+
end
20+
21+
return if base_slug.blank?
22+
1923
if self.class.count > 1
20-
sequence = self.class.where("slug like ?", "%#{slug}%").count
21-
"#{slug}--#{sequence}"
24+
sequence = self.class.where("slug like ?", "%#{base_slug}%").count
25+
"#{base_slug}--#{sequence}"
2226
end
2327
end
2428

2529
def slug_candidates
26-
case self.class
27-
when "Review"
30+
case self
31+
when Review
2832
[
2933
[cleanup(book.sort_title)],
3034
[:title_and_sequence]
3135
]
32-
when "Book"
36+
when Book
3337
[
3438
[cleanup(sort_title)],
3539
[:title_and_sequence]
3640
]
41+
when Region
42+
[
43+
[cleanup(title), rights_check],
44+
[:title_and_sequence]
45+
]
3746
else
3847
[
3948
[cleanup(title)],
@@ -45,4 +54,17 @@ def slug_candidates
4554
def cleanup(html)
4655
ActionController::Base.helpers.strip_tags(html)
4756
end
57+
58+
def rights_check
59+
case rights_designation
60+
when "exclusive", 2
61+
"exclusive-rights"
62+
when "non_exclusive", 1
63+
"non-exclusive-rights"
64+
when "world_exclusive", 3
65+
"world-exclusive-rights"
66+
else
67+
""
68+
end
69+
end
4870
end

app/models/person.rb

Lines changed: 30 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -17,6 +17,25 @@ def name
1717
title
1818
end
1919

20+
def region_record
21+
return nil if region.blank?
22+
23+
@region_record ||= begin
24+
normalized = region.to_s.sub(/\s*\(.*\)\s*\z/, "").strip
25+
base_name = normalized.gsub(/\b(world\s+exclusive|non[-\s]?exclusive|exclusive)\b(\s+rights?)?/i, "").strip
26+
scope = Region.where(name: [normalized, base_name].uniq)
27+
28+
designation = parsed_rights_designation
29+
scoped_scope = designation ? scope.where(rights_designation: Region.rights_designations[designation]) : scope
30+
31+
scoped_scope.first || scope.first
32+
end
33+
end
34+
35+
def rights_type
36+
region_record&.rights_type
37+
end
38+
2039
def self.search(q)
2140
if q
2241
q = q.last.present? ? q : q[0...-1]
@@ -25,4 +44,15 @@ def self.search(q)
2544
.sort
2645
end
2746
end
47+
48+
private
49+
50+
def parsed_rights_designation
51+
label = region.to_s.downcase
52+
return :world_exclusive if label.include?("world exclusive")
53+
return :non_exclusive if label.include?("non-exclusive") || label.include?("non exclusive")
54+
return :exclusive if label.include?("exclusive")
55+
return :unspecified if label.include?("unspecified")
56+
nil
57+
end
2858
end

0 commit comments

Comments
 (0)