Module: QuickbooksCustomerHelper

Extended by:
ActiveSupport::Concern
Includes:
CustomerHierarchyManagement
Included in:
QuickbooksCustomerByCompanyResolver, QuickbooksCustomerResolver, QuickbooksInvoiceHeaderResolver
Defined in:
app/helpers/quickbooks_customer_helper.rb

Overview

QuickbooksCustomerHelper provides methods for processing and formatting QuickBooks customer data to match our internal customer data structure.

This module includes methods to:

  • Extract and format customer data from QuickBooks API responses

  • Find corresponding internal type IDs, currency IDs, and payment terms

  • Extract shipping address information

  • Handle customer hierarchy management

Example usage:

class CustomerImporter
  include QuickbooksCustomerHelper

  def import_quickbooks_customer(qb_customer)
    # Get external reference ID
    external_id = external_reference_code(qb_customer)

    # Format the customer code
    code = formatted_code(qb_customer, 'QB')

    # Get the known_as name
    name = format_known_as(qb_customer)

    # Find the appropriate type
    type_id = find_type(qb_customer['CustomerTypeName'])

    # Extract shipping address
    shipping_address = extract_shipping_address_from_quickbooks_customer(qb_customer)

    # Create customer...
  end
end

Instance Method Summary collapse

Methods included from CustomerHierarchyManagement

#assign_customer_hierarchy, #billing_shipping_addresses_match?, #create_dc_customer_for_shipping_address, #create_member_customer_for_shipping_address, #determine_hierarchy_attributes, #find_customer_with_same_address, #shipping_address_valid?

Methods included from AddressHelper

#canadian_postal_code?, #clean_city, #normalize_postal_code, #parse_address_line, #parse_address_parts, #us_zip_code?, #valid_city?, #valid_state?

Instance Method Details

#check_and_create_member_customer(customer, shipping_address = nil) ⇒ Customer?

Checks if a distribution center customer is needed for the shipping address

Parameters:

  • customer (Customer)

    The customer record

  • shipping_address (Hash, nil) (defaults to: nil)

    The shipping address details

Returns:

  • (Customer, nil)

    The created member customer or nil



144
145
146
# File 'app/helpers/quickbooks_customer_helper.rb', line 144

def check_and_create_member_customer(customer, shipping_address = nil)
  create_member_customer_for_shipping_address(customer, shipping_address)
end

#check_and_set_customer_hierarchy(customer, suffix_code) ⇒ Boolean

Checks and assigns the appropriate hierarchy for a customer

Parameters:

  • customer (Customer)

    The customer record to update

  • suffix_code (String)

    The prefix/suffix code used in the customer code

Returns:

  • (Boolean)

    True if hierarchy was set or already valid, false otherwise



135
136
137
# File 'app/helpers/quickbooks_customer_helper.rb', line 135

def check_and_set_customer_hierarchy(customer, suffix_code)
  assign_customer_hierarchy(customer, suffix_code)
end

#external_reference_code(quickbooks_customer) ⇒ String

Extracts the external reference code (ID) from a QuickBooks customer

Parameters:

  • quickbooks_customer (Hash)

    The customer data from QuickBooks API

Returns:

  • (String)

    The QuickBooks customer ID



44
45
46
# File 'app/helpers/quickbooks_customer_helper.rb', line 44

def external_reference_code(quickbooks_customer)
  quickbooks_customer['Id']
end

#extract_shipping_address_from_quickbooks_customer(quickbooks_customer) ⇒ Hash?

Extracts shipping address details from a QuickBooks customer

Parameters:

  • quickbooks_customer (Hash)

    The customer data from QuickBooks API

Returns:

  • (Hash, nil)

    A hash containing the shipping address details or nil if not present



117
118
119
120
121
122
123
124
125
126
127
128
# File 'app/helpers/quickbooks_customer_helper.rb', line 117

def extract_shipping_address_from_quickbooks_customer(quickbooks_customer)
  return nil unless quickbooks_customer.dig('ShipAddr').present?

  {
    company_name: quickbooks_customer['CompanyName'] || quickbooks_customer['DisplayName'],
    address_line1: quickbooks_customer.dig('ShipAddr', 'Line1'),
    address_line2: quickbooks_customer.dig('ShipAddr', 'Line2'),
    city: quickbooks_customer.dig('ShipAddr', 'City'),
    province_code: quickbooks_customer.dig('ShipAddr', 'CountrySubDivisionCode'),
    postal_code: quickbooks_customer.dig('ShipAddr', 'PostalCode')
  }
end

#find_currency_id(currency_code) ⇒ Integer

Finds the internal currency ID that corresponds to a QuickBooks currency code

Parameters:

  • currency_code (String)

    The currency code from QuickBooks (e.g., ‘CAD’, ‘USD’)

Returns:

  • (Integer)

    The internal currency ID, defaults to CAD_ID if not found



89
90
91
92
93
94
# File 'app/helpers/quickbooks_customer_helper.rb', line 89

def find_currency_id(currency_code)
  return Currency::CAD_ID if currency_code.blank?

  currency = Currency.find_by(code: currency_code)
  currency&.currency_id || Currency::CAD_ID
end

#find_payment_term_id(term_name) ⇒ Integer?

Finds the internal payment term ID that corresponds to a QuickBooks term name

Parameters:

  • term_name (String)

    The payment term name from QuickBooks

Returns:

  • (Integer, nil)

    The internal payment term ID, defaults to immediate payment if not found



100
101
102
103
104
105
106
107
108
109
110
111
# File 'app/helpers/quickbooks_customer_helper.rb', line 100

def find_payment_term_id(term_name)
  if term_name.present?
    # Try to find payment term by name first
    payment_term = PaymentTerm.find_by(description: term_name)
    return payment_term.payment_term_id if payment_term.present?
  end

  # Always fallback to immediate payment, even if term_name is blank
  # From quickbooks, the payment term is 'due on receipt'
  immediate_term = PaymentTerm.find_by(description: 'IMMEDIATLY')
  immediate_term&.payment_term_id
end

#find_type(type_description) ⇒ String

Finds the internal type ID that corresponds to a QuickBooks customer type

Parameters:

  • type_description (String)

    The customer type description from QuickBooks

Returns:

  • (String)

    The internal type ID, defaults to ‘4’ if not found



74
75
76
77
78
79
80
81
82
83
# File 'app/helpers/quickbooks_customer_helper.rb', line 74

def find_type(type_description)
  return '4' unless type_description.present?

  type = TypesMaster.find_by(
    element: 'Customer Type',
    type_description: type_description
  )

  type&.type || '4'
end

#format_known_as(quickbooks_customer) ⇒ String

Formats the customer’s display name from individual name components

Parameters:

  • quickbooks_customer (Hash)

    The customer data from QuickBooks API

Returns:

  • (String)

    The formatted name combining title, given name, and family name



61
62
63
64
65
66
67
68
# File 'app/helpers/quickbooks_customer_helper.rb', line 61

def format_known_as(quickbooks_customer)
  parts = [
    quickbooks_customer['Title'],
    quickbooks_customer['GivenName'],
    quickbooks_customer['FamilyName']
  ].compact
  parts.join(' ')
end

#formatted_code(quickbooks_customer, suffix_code) ⇒ String

Formats a customer code using a prefix/suffix code and the QuickBooks ID

Parameters:

  • quickbooks_customer (Hash)

    The customer data from QuickBooks API

  • suffix_code (String)

    The prefix/suffix code to use (e.g., ‘QB’, ‘QBO’)

Returns:

  • (String)

    The formatted customer code (e.g., ‘QB-12345’)



53
54
55
# File 'app/helpers/quickbooks_customer_helper.rb', line 53

def formatted_code(quickbooks_customer, suffix_code)
  "#{suffix_code}-#{quickbooks_customer['Id']}"
end