Module: NetSuite::Utilities

Extended by:
Utilities
Included in:
Utilities
Defined in:
lib/netsuite/utilities.rb

Instance Method Summary collapse

Instance Method Details

#append_memo(ns_record, added_memo, opts = {}) ⇒ Object

TODO need structured logger for various statements



7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
# File 'lib/netsuite/utilities.rb', line 7

def append_memo(ns_record, added_memo, opts = {})
  opts[:skip_if_exists] ||= false

  memo_key = if ns_record.class == NetSuite::Records::Customer
    :comments
  else
    :memo
  end

  return if opts[:skip_if_exists] &&
    ns_record.send(memo_key) &&
    ns_record.send(memo_key).include?(added_memo)

  if ns_record.send(memo_key)
    ns_record.send(:"#{memo_key}=", "#{ns_record.send(memo_key)}. #{added_memo}")
  else
    ns_record.send(:"#{memo_key}=", added_memo.to_s)
  end

  ns_record
end

#backoff(options = {}) ⇒ Object



29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
# File 'lib/netsuite/utilities.rb', line 29

def backoff(options = {})
  count = 0
  begin
    count += 1
    yield
  rescue options[:exception] || Savon::SOAPFault => e
    if !e.message.include?("Only one request may be made against a session at a time") &&
       !e.message.include?('java.util.ConcurrentModificationException') &&
       !e.message.include?('SuiteTalk concurrent request limit exceeded. Request blocked.')
      raise e
    end
    if count >= (options[:attempts] || 8)
      raise e
    end
    # log.warn("concurrent request failure", sleep: count, attempt: count)
    sleep(count)
    retry
  end
end

#data_center_url(netsuite_account) ⇒ Object



140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
# File 'lib/netsuite/utilities.rb', line 140

def data_center_url()
  begin
    data_center_call_response = NetSuite::Configuration.connection({}, {
      email: '',
      password: '',
      account: ''
    }).call(:get_data_center_urls, message: {
      'platformMsgs:account' => 
    })

    if data_center_call_response.success?
      return data_center_call_response.body[:get_data_center_urls_response][:get_data_center_urls_result][:data_center_urls][:webservices_domain]
    else
      # log.error "error getting data center url"
    end
  rescue Exception => e
    # log.error "error determining correct datacenter for account #{netsuite_account}. #{e.message}"

    # TODO silence this later: for now we need to investigate when this would occur
    raise(e)
  end
end

#find_record(record, names, opts = {}) ⇒ Object



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
# File 'lib/netsuite/utilities.rb', line 100

def find_record(record, names, opts = {})
  field_name = opts[:field_name]

  names = [ names ] if names.is_a?(String)

  # FIXME: Records that have the same name but different types will break
  # the cache
  names.each do |name|
    @netsuite_find_record_cache ||= {}

    if @netsuite_find_record_cache.has_key?(name)
      return @netsuite_find_record_cache[name]
    end

    # sniff for an email-like input; useful for employee/customer searches
    if !field_name && /@.*\./ =~ name
      field_name = 'email'
    end

    field_name ||= 'name'

    # TODO remove backoff when it's built-in to search
    search = backoff { record.search({
      basic: [
        {
          field: field_name,
          operator: 'contains',
          value: name,
        }
      ]
    }) }

    if search.results.first
      return @netsuite_find_record_cache[name] = search.results.first
    end
  end

  nil
end

#get_item(ns_item_internal_id) ⇒ Object



63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
# File 'lib/netsuite/utilities.rb', line 63

def get_item(ns_item_internal_id)
  # TODO add additional item types!
  ns_item = NetSuite::Utilities.get_record(NetSuite::Records::InventoryItem, ns_item_internal_id)
  ns_item ||= NetSuite::Utilities.get_record(NetSuite::Records::AssemblyItem, ns_item_internal_id)
  ns_item ||= NetSuite::Utilities.get_record(NetSuite::Records::NonInventorySaleItem, ns_item_internal_id)
  ns_item ||= NetSuite::Utilities.get_record(NetSuite::Records::NonInventoryResaleItem, ns_item_internal_id)
  ns_item ||= NetSuite::Utilities.get_record(NetSuite::Records::DiscountItem, ns_item_internal_id)
  ns_item ||= NetSuite::Utilities.get_record(NetSuite::Records::OtherChargeSaleItem, ns_item_internal_id)
  ns_item ||= NetSuite::Utilities.get_record(NetSuite::Records::ServiceSaleItem, ns_item_internal_id)
  ns_item ||= NetSuite::Utilities.get_record(NetSuite::Records::GiftCertificateItem, ns_item_internal_id)
  ns_item ||= NetSuite::Utilities.get_record(NetSuite::Records::KitItem, ns_item_internal_id)
  ns_item ||= NetSuite::Utilities.get_record(NetSuite::Records::SerializedInventoryItem, ns_item_internal_id)

  if ns_item.nil?
    fail NetSuite::RecordNotFound, "item with ID #{ns_item_internal_id} not found"
  end

  ns_item
end

#get_record(record_klass, id, opts = {}) ⇒ Object



83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
# File 'lib/netsuite/utilities.rb', line 83

def get_record(record_klass, id, opts = {})
  opts[:external_id] ||= false

  begin
    # log.debug("get record", netsuite_record_type: record_klass.name, netsuite_record_id: id)

    if opts[:external_id]
      return backoff { record_klass.get(external_id: id) }
    else
      return backoff { record_klass.get(id) }
    end
  rescue ::NetSuite::RecordNotFound
    # log.warn("record not found", ns_record_type: record_klass.name, ns_record_id: id)
    return nil
  end
end

#normalize_datetime_from_netsuite(datetime) ⇒ Object

use when displaying times from a NS record



184
185
186
187
188
189
190
# File 'lib/netsuite/utilities.rb', line 184

def normalize_datetime_from_netsuite(datetime)
  # the code below eliminates the TimeZone offset then shifts the date forward 2 hours (7200 seconds)
  # this ensures that ActiveRecord is given a UTC0 DateTime with the exact hour that
  # was displayed in the NS UI (CST time zone), which will result in the correct display on the web side

  datetime.new_offset(0) + datetime.offset + Rational(2, 24)
end

#normalize_datetime_to_netsuite(datetime) ⇒ Object

use when sending times to NS



173
174
175
176
177
178
179
180
181
# File 'lib/netsuite/utilities.rb', line 173

def normalize_datetime_to_netsuite(datetime)
  # normalize the time to UCT0
  # add 6 hours (21600 seconds) of padding (CST offset)
  # to force the same time to be displayed in the NS UI

  is_dst = Time.parse(datetime.to_s).dst?

  datetime.new_offset(0) + datetime.offset + Rational(is_dst ? 5 : 6, 24)
end

#request_failed?(ns_object) ⇒ Boolean

Returns:

  • (Boolean)


49
50
51
52
53
54
55
56
57
58
59
60
# File 'lib/netsuite/utilities.rb', line 49

def request_failed?(ns_object)
  return false if ns_object.errors.nil? || ns_object.errors.empty?

  warnings = ns_object.errors.select { |x| x.type == "WARN" }
  errors = ns_object.errors.select { |x| x.type == "ERROR" }

  # warnings.each do |warn|
  #   log.warn(warn.message, code: warn.code)
  # end

  return errors.size > 0
end