Importa i prospect Calcio a 5 senza toccare la Pallavolo e filtra le organizzazioni per sport.
Co-authored-by: Cursor <cursoragent@cursor.com>
This commit is contained in:
@@ -5,6 +5,7 @@ class OrganizationsController < ApplicationController
|
||||
|
||||
def index
|
||||
@page_title = "Organizzazioni"
|
||||
@sport_options = organizations_for_current_project.where.not(sport: [ nil, "" ]).distinct.order(:sport).pluck(:sport)
|
||||
scope = organizations_for_current_project.includes(:assigned_user, :contacts, :opportunities, :tasks, :projects)
|
||||
scope = scope.search(params[:q]) if params[:q].present?
|
||||
scope = apply_filters(scope)
|
||||
|
||||
@@ -3,8 +3,9 @@ require "csv"
|
||||
class CampaignImport::MatchlivetvLaunch
|
||||
CAMPAIGN_NAME = "Campagna lancio 01".freeze
|
||||
SPORT = "Pallavolo".freeze
|
||||
LEGAL_PREFIXES = /\b(ssdarl|ssd arl|a\.?s\.?d\.?|asd|s\.?s\.?d\.?|ssd|s\.?s\.?|a\.?f\.?|a\.?p\.?|c\.?s\.?|polisportiva)\b/i
|
||||
|
||||
Result = Struct.new(:wiped_organizations, :imported, :errors, keyword_init: true)
|
||||
Result = Struct.new(:wiped_organizations, :imported, :skipped, :errors, keyword_init: true)
|
||||
|
||||
STREAMING_MAP = {
|
||||
"NON RILEVATO" => "not_detected",
|
||||
@@ -27,11 +28,13 @@ class CampaignImport::MatchlivetvLaunch
|
||||
"NON INVIARE" => "no_send"
|
||||
}.freeze
|
||||
|
||||
def initialize(path:, user: nil, project: nil, wipe: true)
|
||||
def initialize(path:, user: nil, project: nil, wipe: true, sport: SPORT, campaign_name: CAMPAIGN_NAME)
|
||||
@path = Pathname.new(path)
|
||||
@user = user
|
||||
@project = project
|
||||
@wipe = wipe
|
||||
@sport = sport
|
||||
@campaign_name = campaign_name
|
||||
end
|
||||
|
||||
def call
|
||||
@@ -43,17 +46,27 @@ class CampaignImport::MatchlivetvLaunch
|
||||
Current.project = @project
|
||||
|
||||
wiped = @wipe ? wipe_project! : 0
|
||||
index_existing_names!
|
||||
imported = 0
|
||||
skipped = 0
|
||||
errors = []
|
||||
|
||||
rows.each_with_index do |row, idx|
|
||||
name = cell(row, "Società")
|
||||
if duplicate_name?(name)
|
||||
skipped += 1
|
||||
next
|
||||
end
|
||||
|
||||
import_row!(row)
|
||||
remember_name!(name)
|
||||
imported += 1
|
||||
rescue StandardError => e
|
||||
errors << { line: idx + 2, name: row["Società"], message: e.message }
|
||||
message = e.is_a?(ActiveRecord::RecordInvalid) ? e.record.errors.full_messages.to_sentence : e.message
|
||||
errors << { line: idx + 2, name: row["Società"], message: message }
|
||||
end
|
||||
|
||||
Result.new(wiped_organizations: wiped, imported: imported, errors: errors)
|
||||
Result.new(wiped_organizations: wiped, imported: imported, skipped: skipped, errors: errors)
|
||||
ensure
|
||||
Current.user = nil
|
||||
Current.project = nil
|
||||
@@ -88,11 +101,11 @@ class CampaignImport::MatchlivetvLaunch
|
||||
org = Organization.new(
|
||||
name: name,
|
||||
organization_type: "societa_sportiva",
|
||||
sport: SPORT,
|
||||
sport: @sport,
|
||||
country: "Italia",
|
||||
region: cell(row, "Regione"),
|
||||
province: cell(row, "Prov."),
|
||||
email: cell(row, "Email verificata")&.downcase,
|
||||
email: normalize_email(cell(row, "Email verificata")),
|
||||
website: cell(row, "Sito / profilo"),
|
||||
source_url: cell(row, "Fonte contatto / ricerca"),
|
||||
commercial_fit: cell(row, "Evidenza / fit commerciale"),
|
||||
@@ -129,10 +142,10 @@ class CampaignImport::MatchlivetvLaunch
|
||||
end
|
||||
|
||||
org.opportunities.create!(
|
||||
name: CAMPAIGN_NAME,
|
||||
name: @campaign_name,
|
||||
project: @project,
|
||||
pipeline_stage: stage,
|
||||
product: cell(row, "Piano"),
|
||||
product: blank_if_no(cell(row, "Piano")),
|
||||
assigned_user: @user,
|
||||
ab_variant: cell(row, "Test A/B").to_s.upcase.presence,
|
||||
send_status: SEND_MAP.fetch(normalize_key(cell(row, "Stato invio")), "to_send"),
|
||||
@@ -144,6 +157,43 @@ class CampaignImport::MatchlivetvLaunch
|
||||
)
|
||||
end
|
||||
|
||||
def index_existing_names!
|
||||
@existing_names = {}
|
||||
Organization.find_each { |org| remember_name!(org.name) }
|
||||
end
|
||||
|
||||
def remember_name!(name)
|
||||
key = normalize_org_name(name)
|
||||
@existing_names[key] = true if key.present?
|
||||
end
|
||||
|
||||
def duplicate_name?(name)
|
||||
key = normalize_org_name(name)
|
||||
key.blank? || @existing_names[key]
|
||||
end
|
||||
|
||||
def normalize_org_name(name)
|
||||
I18n.transliterate(name.to_s)
|
||||
.downcase
|
||||
.gsub("'", " ")
|
||||
.gsub(LEGAL_PREFIXES, " ")
|
||||
.gsub(/[^a-z0-9]+/, " ")
|
||||
.squeeze(" ")
|
||||
.strip
|
||||
end
|
||||
|
||||
def blank_if_no(value)
|
||||
return if value.blank?
|
||||
return if %w[NO N/A].include?(normalize_key(value))
|
||||
|
||||
value
|
||||
end
|
||||
|
||||
def normalize_email(value)
|
||||
email = value.to_s.strip.downcase.gsub(/\s+/, "")
|
||||
email.presence
|
||||
end
|
||||
|
||||
def cell(row, header)
|
||||
value = row[header].to_s.strip
|
||||
value.presence
|
||||
|
||||
@@ -16,7 +16,7 @@
|
||||
<%= select_tag :owner, options_from_collection_for_select(User.active.order(:first_name), :id, :full_name, params[:owner]), include_blank: "Owner", class: input_class %>
|
||||
<%= select_tag :lead_source, options_for_catalog(Catalog::LEAD_SOURCES, params[:lead_source]), include_blank: "Fonte", class: input_class %>
|
||||
<%= select_tag :organization_type, options_for_catalog(Catalog::ORGANIZATION_TYPES, params[:organization_type]), include_blank: "Tipologia", class: input_class %>
|
||||
<%= text_field_tag :sport, params[:sport], placeholder: "Sport", class: input_class %>
|
||||
<%= select_tag :sport, options_for_select(@sport_options, params[:sport]), include_blank: "Sport", class: input_class %>
|
||||
<%= text_field_tag :country, params[:country], placeholder: "Paese", class: input_class %>
|
||||
<%= text_field_tag :region, params[:region], placeholder: "Regione", class: input_class %>
|
||||
<%= select_tag :customer, options_for_select([["Cliente/non cliente", ""], ["Solo clienti", "yes"], ["Non clienti", "no"]], params[:customer]), class: input_class %>
|
||||
|
||||
Reference in New Issue
Block a user