Class: DataImportRow
- Inherits:
-
ApplicationRecord
- Object
- ActiveRecord::Base
- ApplicationRecord
- DataImportRow
- Defined in:
- app/models/data_import_row.rb
Overview
== Schema Information
Table name: data_import_rows
Database name: primary
id :integer not null, primary key
import_errors :text
import_state :enum default("not_imported"), not null
row_index :integer
customer_id :integer
data_import_id :integer
Indexes
idx_data_import_rows_unique (data_import_id,row_index) UNIQUE
index_data_import_rows_on_customer_id (customer_id)
Foreign Keys
data_import_rows_data_import_id_fk (data_import_id => data_imports.id) ON DELETE => cascade
fk_rails_... (customer_id => parties.id) ON DELETE => nullify
fk_rails_... (data_import_id => data_imports.id) ON DELETE => cascade
Constant Summary
Constants included from Models::Schedulable
Models::Schedulable::SIMPLE_FORM_OPTIONS
Belongs to collapse
Has many collapse
Class Method Summary collapse
-
.name_cleanup(target_value) ⇒ String
Capitalizes each word in the value for name fields.
Instance Method Summary collapse
-
#import(logger = nil) ⇒ Hash{Symbol=>Object}
Imports this row into a new Customer using the linked cells.
Methods inherited from ApplicationRecord
ransackable_associations, ransackable_attributes, ransackable_scopes, ransortable_attributes, #to_relation
Methods included from Models::Schedulable
Methods included from Models::AfterCommittable
Methods included from Models::EventPublishable
Class Method Details
.name_cleanup(target_value) ⇒ String
Capitalizes each word in the value for name fields.
42 43 44 |
# File 'app/models/data_import_row.rb', line 42 def self.name_cleanup(target_value) target_value.split.map(&:capitalize).join(' ') end |
Instance Method Details
#customer ⇒ Customer?
28 |
# File 'app/models/data_import_row.rb', line 28 belongs_to :customer, optional: true, inverse_of: :data_import_row |
#data_import ⇒ DataImport
30 |
# File 'app/models/data_import_row.rb', line 30 belongs_to :data_import, inverse_of: :data_import_rows |
#data_import_cells ⇒ ActiveRecord::Relation<DataImportCell>
33 |
# File 'app/models/data_import_row.rb', line 33 has_many :data_import_cells, inverse_of: :data_import_row |
#import(logger = nil) ⇒ Hash{Symbol=>Object}
Imports this row into a new Customer using the linked cells.
49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 |
# File 'app/models/data_import_row.rb', line 49 def import(logger = nil) return { status: :invalid_state } unless queued? return { status: :already_imported } if customer logger ||= Rails.logger logger.info "Import triggered on data import row #{id}" c = Customer.new begin Customer.transaction do c.source_id = data_import.source_id c.state = data_import.initial_state # c.reception_type = self.data_import.reception_type c.perform_lead_verification = true c.must_have_one_contact = false notes = ["Import Details created from import #{data_import.name} (id: #{data_import_id})"] address = nil logger.debug 'Starting Cell Processing' data_import_cells.each do |cell| next unless (dds = cell.data_import_column&.data_dictionary_set) next unless (target_value = cell.target_value) target_object, target_field = dds.destination.split('.') case target_object.to_sym when :customer target_value = self.class.name_cleanup(target_value) if /name/.match?(target_field) c.affiliations << target_value if target_field == 'customer.affiliation' && target_value.present? if target_field == 'person_name' pnp = PersonNameParser.new(target_value) c.full_name = pnp.full_name # This sorts people name back in a normalized form, e.g Smith, John becomes John Smith company name else c.send "#{target_field}=", target_value end when :contact contact = c.contacts.first || c.contacts.build if /name/.match?(target_field) target_value = self.class.name_cleanup(target_value) if target_field == 'full_name' PersonNameParser.new(target_value).to_party(contact) else contact.send "#{target_field}=", target_value end end when :billing_address if target_field == 'full_address' # parse and explode the address first if (addr = Address::NormalizedAddress.from_string(target_value)) address ||= c.addresses.build(disable_address_correction: true) address.disable_address_correction = true address.street1 = addr.address_line1 address.street2 = addr.address_line2 address.city = addr.city address.state_code = addr.state_code address.zip = addr.postal_code address.country_iso3 = Country.iso_to_iso3_map[addr.country_iso] address.lng = addr.longitude address.lat = addr.latitude else # unparseable address so report in notes notes << "address unrecognized: #{target_value}" end else address ||= c.addresses.build(disable_address_correction: data_import.disable_address_correction) address.send "#{target_field}=", target_value end when :notes notes << "#{cell.data_import_column.name}: #{cell.content}" end end logger.debug 'Cell Processing Complete' country_iso3_default = data_import.default_country_iso3 || 'USA' if address # some default logger.debug 'Address processing' address.country_iso3 ||= country_iso3_default country_iso3_default = address.country_iso3 # in case of change logger.debug "Address processing complete, final address is #{address}" end # A country always override the catalog c.catalog = Catalog.default_for_country(country_iso3_default) c.profile ||= data_import.try(:default_profile) c.profile ||= Profile.find_by(name: 'Unknown') if c.company_name.present? c. ||= data_import.try(:default_buying_group) c.tier2_program_pricing ||= c..try(:tier2_program_pricing) c.tier2_program_pricing ||= c.profile.try(:tier2_program_pricing) c.tier2_program_pricing ||= data_import.try(:tier2_program_pricing) c.affiliations ||= [*c.affiliations, data_import.default_affiliation].filter_map(&:presence).uniq c.primary_sales_rep_id = data_import.default_primary_sales_rep_id if c.save update(import_state: :complete, customer_id: c.id, import_errors: nil) c.quick_note(notes.join("\n")) if notes.present? if data_import.activity_type.present? logger.info "Creating activity for new imported customer id #{c.id} from data import row #{id}" target_datetime = data_import.activity_resource ? data_import.activity_resource.next_working_day : Time.current target_datetime += data_import.activity_schedule_offset_days.days if data_import.activity_schedule_offset_days.present? Activity.create(activity_type_id: data_import.activity_type_id, assigned_resource_id: data_import.activity_assigned_resource_id, description: data_import.activity_description, new_note: data_import.activity_notes, target_datetime: target_datetime, creator_id: data_import.updater_id || data_import.creator_id, party_id: c.contacts.first&.id || c.id) end else update(import_state: :not_imported, import_errors: c.errors_to_s) end end rescue StandardError => e update(import_state: :not_imported, import_errors: "Exception occured while processing: #{e}. #{e.backtrace.first(10).join("\n")}") end { status: import_state.to_sym, import_errors: import_errors, customer: customer } end |