Module: Crm::RetailersHelper
- Defined in:
- app/helpers/crm/retailers_helper.rb
Overview
View helpers for the /retailers dashboards: the deep-linked metric cells
(shared data mapping with the compliance email via
Retailer::DailyComplianceReport.query_params_for), health scoring, and the
CatalogDataPoint-backed trend badges.
Constant Summary collapse
- COLUMN_LABELS =
Column header labels, in COUNT_COLUMNS order.
{ active_public: 'Active & Public', map_violations: 'MAP Violations', promotions: 'Promotions', price_diverging: 'Price Diverging', out_of_stock_active: 'Out of Stock (our inv.)', listing_issues: 'Listing Issues', scrape_failures: 'Scrape Failures', unreachable_online: 'Unreachable Online', out_of_stock_online: 'Out of Stock Online' }.freeze
- DANGER_METRICS =
Metrics coloured red when non-zero (a problem, not just informational).
%i[map_violations price_diverging out_of_stock_active listing_issues scrape_failures unreachable_online out_of_stock_online].freeze
Instance Method Summary collapse
-
#amazon_sales_rank_change(change) ⇒ ActiveSupport::SafeBuffer
Accessible 30-day movement label for an Amazon sales rank.
-
#health_class(pct) ⇒ String
Bootstrap contextual class for a health percentage.
-
#metric_trend_badge(catalog, metric) ⇒ ActiveSupport::SafeBuffer?
Trend badge for one metric from CatalogDataPoint history: an arrow in the direction the raw count moved, coloured by whether that's an improvement.
-
#retailer_health(row) ⇒ Integer
% of active items with no problem state (health gauge / column).
-
#retailer_metric_cell(row, metric) ⇒ ActiveSupport::SafeBuffer
A numeric table cell: links a positive count to its filtered CRM list (ProductCatalogSearch, or the Listing Issues dashboard), red when it's a non-zero problem metric.
-
#retailer_metric_url(catalog_id, metric) ⇒ String?
Deep-link path for a metric's filtered list, or nil.
-
#retailer_type_badge(row) ⇒ ActiveSupport::SafeBuffer
1P/3P badge.
Instance Method Details
#amazon_sales_rank_change(change) ⇒ ActiveSupport::SafeBuffer
Accessible 30-day movement label for an Amazon sales rank. Rank is
inverted: moving from #100 to #70 is a 30-position improvement.
114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 |
# File 'app/helpers/crm/retailers_helper.rb', line 114 def amazon_sales_rank_change(change) if change.nil? tag.span('No 30-day baseline', class: 'text-body-secondary small') elsif change.positive? tag.span(class: 'text-success text-nowrap') do safe_join([fa_icon('arrow-up'), " Improved #{number_with_delimiter(change)}"]) end elsif change.negative? tag.span(class: 'text-danger text-nowrap') do safe_join([fa_icon('arrow-down'), " Worsened #{number_with_delimiter(change.abs)}"]) end else tag.span('Unchanged', class: 'text-body-secondary text-nowrap') end end |
#health_class(pct) ⇒ String
Bootstrap contextual class for a health percentage.
73 74 75 76 77 78 79 |
# File 'app/helpers/crm/retailers_helper.rb', line 73 def health_class(pct) case pct when 90..100 then 'success' when 70..89 then 'warning' else 'danger' end end |
#metric_trend_badge(catalog, metric) ⇒ ActiveSupport::SafeBuffer?
Trend badge for one metric from CatalogDataPoint history: an arrow in the
direction the raw count moved, coloured by whether that's an improvement.
Returns nil until at least two data points exist.
96 97 98 99 100 101 102 103 104 105 106 107 108 |
# File 'app/helpers/crm/retailers_helper.rb', line 96 def metric_trend_badge(catalog, metric) cmp = catalog.data_points.period_comparison(metric) return if cmp.nil? || cmp[:change_percent].to_f.zero? rose = cmp[:change_percent].to_f.positive? inverted = CatalogDataPoint::INVERTED_METRICS.include?(metric.to_s) good = rose ? !inverted : inverted icon = rose ? 'arrow-up' : 'arrow-down' tag.span(class: "small #{good ? 'text-success' : 'text-danger'}") do safe_join([fa_icon(icon, family: :solid), " #{cmp[:change_percent].abs}%"]) end end |
#retailer_health(row) ⇒ Integer
% of active items with no problem state (health gauge / column).
62 63 64 65 66 67 68 |
# File 'app/helpers/crm/retailers_helper.rb', line 62 def retailer_health(row) active = row[:active_public].to_i return 100 if active.zero? pct = (1.0 - (row[:problem_items].to_i.to_f / active)) * 100 pct.round.clamp(0, 100) end |
#retailer_metric_cell(row, metric) ⇒ ActiveSupport::SafeBuffer
A numeric table cell: links a positive count to its filtered CRM list
(ProductCatalogSearch, or the Listing Issues dashboard), red when it's a
non-zero problem metric.
33 34 35 36 37 38 39 40 41 42 43 44 45 |
# File 'app/helpers/crm/retailers_helper.rb', line 33 def retailer_metric_cell(row, metric) val = row[metric].to_i danger = val.positive? && DANGER_METRICS.include?(metric) url = val.positive? ? retailer_metric_url(row[:catalog_id], metric) : nil classes = ['text-end', 'font-monospace', ('text-danger fw-semibold' if danger)].compact.join(' ') inner = if url link_to(val, url, class: danger ? 'text-danger' : nil) else val.to_s end tag.td(inner, class: classes) end |
#retailer_metric_url(catalog_id, metric) ⇒ String?
Deep-link path for a metric's filtered list, or nil.
51 52 53 54 55 56 57 |
# File 'app/helpers/crm/retailers_helper.rb', line 51 def retailer_metric_url(catalog_id, metric) if metric == :listing_issues listing_issues_path(catalog_id:, status: 'open') elsif (qp = Retailer::DailyComplianceReport.query_params_for(metric, catalog_id)) execute_search_path(type: 'ProductCatalogSearch', search: { query_params: qp }) end end |
#retailer_type_badge(row) ⇒ ActiveSupport::SafeBuffer
1P/3P badge.
84 85 86 87 88 |
# File 'app/helpers/crm/retailers_helper.rb', line 84 def retailer_type_badge(row) vendor = row[:retailer_type] == 'vendor' tag.span(vendor ? '1P' : '3P', class: "badge #{vendor ? 'bg-primary-subtle text-primary-emphasis' : 'bg-secondary-subtle text-secondary-emphasis'}") end |