Skip to main content

NetSuite - Customer sync

NetSuite Connector - Customer Update This document describes the Customer Update pipeline within the NetSuite connector. It details h...

Updated over a week ago

NetSuite Connector - Customer Update

This document describes the Customer Update pipeline within the NetSuite connector. It details how customer data, including associated addresses, contact persons, dashboards, notes, price list links, fixed item filters, and customer-specific item class discounts, is processed and synchronized into the App4Sales platform. The update process handles data validation, transformation, and mapping to ensure data integrity and consistency.

Data Source Configuration

The NetSuite connector (or any other connector utilizing this handler) is responsible for fetching customer data from the external ERP system and transforming it into a list of Customer objects. This handler then processes these pre-structured Customer objects and their related entities (Addresses, ContactPersons, etc.) for insertion or update into the App4Sales internal database. Therefore, the specific data source configuration (e.g., NetSuite API endpoints, authentication) is handled upstream by the respective connector's implementation of the customer data retrieval.

Customer Core Fields

App4Sales Field

Source Field (API/Excel/DB)

Logic/Notes

CustomerCode

Customer.CustomerCode

Required. Used as a unique identifier. If empty, customer is skipped.

CustomerName

Customer.CustomerName

Required. If empty, customer is skipped.

CustomerGuid

Customer.CustomerGuid, Customer.CustomerCode, Customer.CustomerName

Unique identifier for the customer.

  • If in "Updater" mode, attempts to reuse GUID from previously inactive customers (`~{CustomerCode}-GUID`) for reactivation.

  • If not found in reactivation links, attempts to retrieve from local cache based on `CustomerCode`.

  • If still empty, calls Portal API to retrieve based on `CustomerCode` and `CustomerName`.

  • If no existing GUID is found, a new GUID is generated.

Created

Customer.Created

If the source value is default (DateTime.MinValue), it defaults to the current timestamp. Truncated to seconds.

Sysmodified

Customer.Sysmodified

Timestamp of last modification. Truncated to seconds.

PasswordWebshop

Customer.PasswordWebshop

Set to null if the connector is running in "Updater" mode.

CustomerDashboard

Customer.CustomerDashboard

If not empty or whitespace, attempts to convert the Base64-encoded string to a byte array and stores it as a dashboard via the customer data manager. The field itself is then set to null to save memory.

LanguageCode

Customer.LanguageCode

If provided, the language code is mapped using configured MappedLanguages. If a mapping exists, the LanguageCode is updated to the mapped value.

ActionPriceList

Customer.ActionPriceList

If DefaultActionPriceListCode is configured in connector settings and ActionPriceList is not explicitly set, it defaults to the ID of the price list corresponding to DefaultActionPriceListCode.

PaymentConditionCode

Customer.PaymentConditionCode

If empty, set to null to prevent foreign key issues.

Email

Customer.Email

Whitespace is trimmed from the email address.

DynamicFreeFields

Customer.DynamicFreeFields

If the field contains non-empty XML (excluding </extraFields> or <extraFields />), it is deserialized from XML to DynamicFreeFields object and then converted to structured extra fields using predefined customer extra field definitions.

VAT Code

Customer.VatCode

Set to null if the administration is configured for the USA.

VAT Liable

Customer.VatLiable

Set to false if the administration is configured for the USA.

FreeFields

Customer.FreeFieldList

If FreeFields is empty and FreeFieldList contains items, FreeFieldList is serialized to XML and stored in FreeFields.

ItemFilter

Customer.ItemFilter, CsvCustomer.UnknownElements

If CustomerItemFilter setting is enabled:

  • If not in "Updater" mode, the existing ItemFilter from the database is retained if the customer exists.

  • Can be populated from CsvCustomer.UnknownElements if the source includes ItemFilter_ prefixed fields.

Addresses

App4Sales Field

Source Field (API/Excel/DB)

Logic/Notes

CustomerGuid

Customer.CustomerGuid

Set to the GUID of the parent customer.

AddressId

Address.AddressId (ExternalId)

If empty, a default ID is generated. Addresses are filtered to exclude empty ones unless they have an ExternalId. If a missing Visit/Delivery address is inferred, its AddressId is reset to null to avoid duplication.

AddressType

Address.AddressType

If empty, defaults to Visit. If only one of Visit or Delivery address types exists for a customer, the missing type is automatically created by duplicating the existing one. If neither Visit nor Delivery exist but other address types are present, a Visit and Delivery address are created from an existing address.

Iso2

Address.Iso2, Address.Country

Country code.

  • Mapped using pre-configured MappedCountries (case-insensitive trim matching).

  • If no mapping found, trimmed.

  • If empty after mapping, attempts to derive it from Country field.

Country

Address.Country, Address.Iso2

If empty, defaults to Iso2.

Email

Address.Email, Customer.Email, ContactPerson.Email

  • Unicode unit separator characters (ASCII 0x001F) are removed, and whitespace is trimmed.

  • If address email is empty and it's the main address:

  • Attempts to inherit email from Customer.Email.

  • If customer email is empty, searches other customer addresses for an email.

  • If still not found, searches customer's contact persons for an email.

AddressLine

Address.AddressLine1

If AddressLine (structured street, house number, addition) is null, it is parsed from AddressLine1 using AddressUtils.ParseAddress. If AddressLine is present, AddressLine1 is formatted from its components.

Street

Derived from AddressLine

Extracted from structured AddressLine or parsed from AddressLine1.

HouseNumber

Derived from AddressLine

Extracted from structured AddressLine or parsed from AddressLine1.

Addition

Derived from AddressLine

Extracted from structured AddressLine or parsed from AddressLine1.

IsMainAddress

Derived

If no Visit addresses are marked as main, the first Visit address is set as main. Same logic applies to Delivery addresses.

Contacts

App4Sales Field

Source Field (API/Excel/DB)

Logic/Notes

CustomerGuid

Customer.CustomerGuid

Set to the GUID of the parent customer.

Email

ContactPerson.Email

Whitespace is trimmed from the email address.

FirstName

ContactPerson.FullName, ContactPerson.FirstName

If FirstName, MiddleName, and LastName are all empty, and FullName is provided, FullName is parsed to extract FirstName. Otherwise, uses source FirstName.

MiddleName

ContactPerson.FullName, ContactPerson.MiddleName

If FirstName, MiddleName, and LastName are all empty, and FullName is provided, FullName is parsed to extract MiddleName. Otherwise, uses source MiddleName.

LastName

ContactPerson.FullName, ContactPerson.LastName

If FirstName, MiddleName, and LastName are all empty, and FullName is provided, FullName is parsed to extract LastName. Otherwise, uses source LastName.

FullName

ContactPerson.FullName, ContactPerson.FirstName, ContactPerson.MiddleName, ContactPerson.LastName

If FullName is empty, it is constructed from FirstName, MiddleName, and LastName.

Initials

ContactPerson.FirstName

Derived from the first character of FirstName.

IsMainContactPerson

ContactPerson.IsMainContactPerson, Customer.MainContactPerson

  • If Customer.MainContactPerson is explicitly set, that contact is marked as main.

  • If a contact in the list matches Customer.MainContactPerson (by FullName or ContactId), it is marked as main.

  • If no main contact is explicitly designated and contacts exist, the first contact in the list is set as main.

ContactId

ContactPerson.ContactId

If in "Updater" mode and ContactId is empty, a hash code is generated as a unique identifier.

DynamicFreeFields

ContactPerson.DynamicFreeFields

If the field contains non-empty XML, it is deserialized from XML to DynamicFreeFields object and then converted to structured extra fields using predefined contact person extra field definitions.

Extra Data & Free Fields

App4Sales Field

Source Field (API/Excel/DB)

Logic/Notes

(Customer Properties)

CsvCustomer (from FTP/CSV extra data)

If supplementary CsvCustomer data is available (e.g., from FTP/CSV import), non-dictionary properties of the CsvCustomer object will overwrite matching properties in the main Customer object.

Customer.FreeFieldList

CsvCustomer.UnknownElements (FreeField_ prefixed keys)

Keys in CsvCustomer.UnknownElements that start with FreeField_ (case-insensitive) and have non-empty values are converted into CustomerFreeField entries. The key (without the prefix) becomes the Caption, and the value becomes the Content.

Customer.ItemFilter

CsvCustomer.UnknownElements (ItemFilter_ prefixed keys)

If SyncSettings.CustomerItemFilter is enabled: Keys in CsvCustomer.UnknownElements that start with ItemFilter_ (case-insensitive) and have non-empty values are processed. The values (which can be ~-separated) are matched against the system's item class map. Valid item class value combinations are formatted into a query string and applied as a customer-specific item filter.

Discounts & Dashboards

App4Sales Field

Source Field (API/Excel/DB)

Logic/Notes

ItemClassValueDiscount.CustomerGuid

Customer.CustomerGuid

Each item class discount is linked to the parent customer's GUID. Only discounts with a value greater than 0 are processed.

CustomerDashboard

Customer.CustomerDashboard (Base64 encoded string)

If provided and not empty, the Base64-encoded string is decoded into binary data. This binary data is then stored as a customer dashboard via the customer data manager. The original CustomerDashboard field on the customer object is cleared after processing.

CustomerNotes

Customer.CustomerNote

If Customer.CustomerNote is provided, any existing "BackOffice" notes for the customer are deleted. A new note is created in the database with "BackOffice" as the sales representative and subject, using the provided note content.

Special Logic & Filters

Input Validation & Filtering

  • Customers with empty CustomerName or CustomerCode are considered invalid and are skipped from the update process. A warning is logged for these skipped customers.

Identifiers & Reactivation

  • Customer GUID Management: The system prioritizes maintaining stable CustomerGuid values. It first attempts to retrieve an existing GUID:

    • For customers that might be reactivated (indicated by a ~ prefix in their code), it checks a specific reactivation cache.

    • Otherwise, it checks a general cache of existing customer codes and GUIDs.

    • If a GUID is still not found, the App4Sales Portal API is queried using the customer code and name.

    • If no existing GUID is identified through these methods, a new unique GUID is generated for the customer.

Localization & Classification

  • Language Code Mapping: Incoming LanguageCode values from the source system are mapped against pre-configured App4Sales MappedLanguages. If a match is found, the customer's LanguageCode is updated to the App4Sales standard.

  • Country Code Normalization: Address country codes (Iso2) are normalized using administrator-defined MappedCountries, ensuring consistency in country representation.

  • Customer Item Filters: If enabled via settings, customer-specific item filters can be processed from extra data. These filters define which item classes and values are applicable for a given customer.

Price Lists & Commercial Settings

  • Price List Deduplication: If the "Enable Price Deduplication" setting is active, customer price list assignments (UsesPriceField and ActionPriceList) are adjusted according to a migration lookup table. This ensures that customers are linked to the correct, deduplicated price lists.

  • Default Action Price List: If an explicit ActionPriceList is not provided for a customer and a DefaultActionPriceListCode is configured in the connector settings, the customer is assigned this default action price list.

  • Payment Condition Cleanup: Empty payment condition codes are converted to null to prevent database errors related to foreign key constraints.

  • USA VAT Rules: For App4Sales administrations configured for the USA, customer VAT code and VAT liability are automatically set to null and false, respectively, reflecting US tax regulations.

Conditional Logic & Flow Control

  • Batch Processing: Customer updates are processed in batches of 100 records. This approach optimizes performance and resource usage when dealing with large datasets.

  • Scripting Hooks: The handler executes custom scripts at various stages of the update process:

    • BeforeUpdateCustomers: Executed before any customer batch processing begins.

    • UpdateCustomers (during batch): Executed for each processed customer within a batch, allowing for real-time adjustments or validations.

    • UpdateCustomers (after all batches): Executed once all customer and contact processing is complete.

  • Updater Mode Behavior: When the connector is running in "Updater" mode (typically for bulk data synchronization):

    • Webshop passwords for customers and contact persons are explicitly set to null.

    • Specific logic for reusing existing CustomerGuid and generating ContactId is applied.

    • Existing InternalCode, ExtraData, and LanguageCode from the database are preserved if the incoming customer data for these fields is empty.

  • Address Processing Control: The entire address processing logic can be conditionally enabled or disabled via the processAddresses parameter in the Update method call.

Error Handling

  • Individual customer processing includes error trapping; exceptions are logged, and the customer update intervals are reset, allowing the system to retry or re-evaluate the update timing.

  • Batch updates for customers, addresses, and item class discounts are also protected by error handling, ensuring that issues in one batch do not halt the entire process and are properly logged.

Related Settings & Prerequisites

The behavior of the Customer Update pipeline is influenced by several connector settings, internal configurations, and system prerequisites:

  • Customer Item Filter: When enabled, this setting (CustomerItemFilter) allows the processing of customer-specific item filters from source data.

  • USA Administration Flag: The system adjusts VAT handling (setting VatCode to null and VatLiable to false) for customers when the administration is designated as a USA entity.

  • Default Action Price List Code: This setting (DefaultActionPriceListCode) specifies a default action price list to be applied to customers who do not have one explicitly defined in the source data.

  • Enable Price Deduplication: When active, this setting enables the migration of customer price list assignments to a deduplicated version, streamlining price management. This relies on the GenericPriceListMigrations lookup table.

  • Mapped Languages: Pre-configured language mappings are essential for normalizing incoming language codes to App4Sales standards.

  • Mapped Countries: Configured country mappings are used to standardize address ISO2 codes, ensuring consistent country identification.

  • Custom Extra Field Definitions: Definitions for custom extra fields for both customers and contact persons must be configured for the proper processing and storage of dynamic free fields.

  • Updater Mode: The system behaves differently when operating in "Updater" mode, affecting aspects like webshop password handling, GUID assignment, and data preservation logic.

  • Script Hooks: Custom logic can be injected via "BeforeUpdateCustomers" and "UpdateCustomers" script hooks, allowing for flexible extensions to the update process.

Known Limitations

  • Hardcoded Price List Fallback: If a customer's primary price list (UsesPriceField) is not found during price deduplication and does not exist, it defaults to price list ID 1.

  • Customer Dashboard Data Not Retained: The raw Base64-encoded string for CustomerDashboard is cleared from the customer object after being processed and stored as binary data. It is not retained in its original string format.

  • Synthetically Generated Contact IDs: In "Updater" mode, if a ContactId is missing for a contact person, a synthetic ID is generated using a hash code. This ID is unique but lacks semantic meaning from the source system.

  • Inferred Address Types: The system will generate default Visit and Delivery addresses if they are absent in the source data but other address types are present. While providing functional addresses, these might not perfectly reflect the address structure in the source ERP.

  • Contact Name Parsing: The contact name parsing logic is noted as an area for future consolidation and may undergo revisions in upcoming versions, indicating it might not yet be fully robust for all edge cases.

Did this answer your question?