NetSuite Connector - Item Update
This function synchronizes item data from NetSuite to App4Sales. It processes various item types, including inventory items, and handles pricing, stock, images, and item categorization. The synchronization runs periodically as configured within the App4Sales platform.
Data Source Configuration
The connector retrieves item data directly from the NetSuite ERP system using its SuiteTalk API.
Items: Fetched via the NetSuite SuiteTalk API using
ItemSearch. Items can be filtered by record type and/or a custom "Yes/No" field.Price Levels & Currencies: Retrieved via
PriceLevelSearchandGetAll(GetAllRecordType.currency)calls to the NetSuite API.Stock Data: Can be retrieved in two ways:
Directly from NetSuite API: Using
service.GetItemsAvailabilityfor item availability records, optionally filtered by specified locations.From NetSuite Servlets: If configured, stock data is fetched from custom NetSuite servlets (scripted endpoints) via HTTP GET requests using OAuth authentication. The servlet URL and authentication details are configured in the connector settings. The JSON response from the servlet is parsed to extract quantity, on-hand quantity, and delivery date.
Customer Pricing Information: Customer-specific pricing data (e.g., pricing groups, item-specific price overrides) is retrieved from an internal ERP response data store, which is populated during the customer synchronization process.
Data Mapping Table: App4Sales Item (Optimizers.App4Sales.Models.ObjectsDb.Item)
App4Sales Field | Source Field (NetSuite) | Logic/Notes |
|
| Directly mapped. |
|
| NetSuite internal ID of the item. |
|
| The NetSuite record type of the item (e.g., "InventoryItem"). |
|
| Directly mapped. |
|
| Directly mapped. |
|
| Mapped from UPC Code. |
|
| Sales unit name. |
|
| 'I' if prices include tax, 'E' if excluded. |
|
| Directly mapped. |
|
| Internal ID of the pricing group. |
|
| True if a pricing group is assigned, false otherwise. |
| Custom Field ( | Date from the NetSuite custom field configured as 'First Possible Ship Date'. |
|
| If |
|
| Mapped based on the NetSuite tax schedule name (if configured in VAT percentage mappings) or falls back to the default item VAT percentage setting. |
|
| Determined from the item's pricing matrix for the configured base price level and default sales price currency. Defaults to the price for quantity 0/1. |
| Stock data ( | The available stock quantity retrieved from NetSuite API or servlets. |
| Custom Field ( | Determined by a custom field in NetSuite, which can be a string, boolean, or select field. Mapped using |
|
| Value of the matrix option identified by the Matrix X Field regex. |
|
| Description of the matrix option identified by the Matrix X Field regex. |
|
| Value of the matrix option identified by the Matrix Y Field regex. (Often empty if MatrixYDescription is present) |
|
| Description of the matrix option identified by the Matrix Y Field regex. |
|
| Name of the parent item for matrix children, if both Matrix X and Y values are identified. |
|
| Internal ID of the parent item for matrix children, if both Matrix X and Y values are identified. |
|
| If |
| Configured via | Mapped from a NetSuite item field or custom field as specified in the JSON mapping. |
| Configured via | Mapped from a NetSuite item field or custom field as specified in the JSON mapping. |
| Configured via | Mapped from a NetSuite item field or custom field as specified in the JSON mapping. |
| Configured via | Mapped from a NetSuite item field or custom field as specified in the JSON mapping. |
| Mapped from the item's class name. | |
|
| Mapped from the item's department name if |
|
| Mapped from the item's pricing group name. |
|
| All custom fields are added as item categories, using their script ID as part of the category name. |
|
| All matrix options are added as item categories, using their script ID as part of the category name. |
|
| Name of the parent item if applicable. |
|
| Mapped from the item's (or parent's) detailed store description. |
|
| Combines weight value and unit (e.g., "10.50 kg") as an item category. |
| Various, based on settings | Contains additional fields as key-value pairs (OptKvp). See special logic for details. |
|
| Images are downloaded from NetSuite based on URLs obtained from |
Data Mapping Table: App4Sales PriceList (Optimizers.App4Sales.Models.PriceList)
App4Sales Field | Source Field (NetSuite) | Logic/Notes |
| Derived | Generated hash code from NetSuite Currency Internal ID and Price Level Internal ID. For customer-specific price lists, a hash code of the customer code is used. |
|
| NetSuite internal ID of the price level. |
|
| Display symbol of the currency (e.g., "€", "$"). |
|
| NetSuite internal ID of the currency. |
| Derived | Combination of currency symbol and price level internal ID (e.g., "€_123" or "Level:123_Currency:€_Customer:CUST001"). |
|
| Name of the NetSuite price level (e.g., "[€] Base Price") or "Customer {customerCode}" for customer-specific price lists. |
| Derived | True for standard price lists, False for customer-specific price lists. |
| Derived | Internal ID of an existing price list if the current price list's data (prices, tier prices) is identical to avoid duplication. |
Data Mapping Table: App4Sales PriceListPrice (Optimizers.App4Sales.Models.PriceListPrice)
App4Sales Field | Source Field (NetSuite) | Logic/Notes |
| Derived | References the generated ID of the associated App4Sales PriceList. |
|
| The App4Sales item code. |
|
| The individual item price. For customer-specific prices, this can be an override or derived from a specific price level in NetSuite. |
Data Mapping Table: App4Sales StafflePrice (Optimizers.App4Sales.Models.StafflePrice)
App4Sales Field | Source Field (NetSuite) | Logic/Notes |
| Derived | References the generated ID of the associated App4Sales PriceList. |
|
| The App4Sales item code. |
|
| The minimum quantity required for this tier price. |
|
| The price for this tier. |
Data Mapping Table: App4Sales Warehouse (Optimizers.App4Sales.Datalayer.Entities.Warehouse)
App4Sales Field | Source Field (NetSuite) | Logic/Notes |
|
| NetSuite internal ID of the location. |
|
| Name of the NetSuite location. |
|
| The NetSuite internal ID of the location is used as the warehouse code. |
|
| True if the location is active, False otherwise. |
Special Logic & Filters
Item Filtering: Only active items are synchronized (
isInactive = false). Items can be further filtered by:Specific NetSuite item record types (e.g.,
InventoryItem,AssemblyItem) defined inConnectorSettings.ItemTypesForSync.A custom "Yes/No" field in NetSuite, specified by
ConnectorSettings.SyncItemsBasedOnCustomYesNoField. If this setting is provided, it overrides item type filtering, and only items with this custom field set to "Yes" are synchronized.
Matrix Item Handling: Parent matrix items are explicitly skipped during synchronization (
item.matrixType == _parent). Only matrix child items are processed, and the connector constructs the matrix relationship in App4Sales based on these children. This means that App4Sales does not receive parent items as standalone products but rather groups variants under a conceptual parent.Stock Data Retrieval:
By default, stock data is retrieved from NetSuite's item availability records.
If
ConnectorSettings.RetrieveStockDataUsingServletsis enabled, stock data is retrieved from a custom NetSuite servlet, which allows for highly customized stock logic within NetSuite.Stock quantities are aggregated by item, and can be split by location/warehouse.
The "To Be Received" stock quantity can be read from a custom field in NetSuite (
ConnectorSettings.ToBeReceivedStockCustomFieldName).
Price Deduplication: The connector checks for identical price list data (base prices and tier prices) to avoid creating duplicate price lists in App4Sales. If a new price list's data matches an existing one, the new price list is marked as a duplicate of the existing one.
Item Description Mapping: The
ConnectorSettings.ItemsDescriptionsMappingallows flexible mapping of NetSuite item properties or custom fields to App4Sales item description fields (Description2-5).Item Field Mapping: The
ConnectorSettings.ItemFieldsMappingallows flexible mapping of NetSuite item properties or custom fields to other App4Sales item fields or additional Item Categories.Concurrency: Picture downloading is performed concurrently, with the degree of parallelism controlled by
ConnectorSettings.DownloadPicturesConcurrencyLimit.
Domain Specifics (Expanded)
Price Logic
The connector retrieves and processes item pricing from NetSuite, including base prices, tier prices, and customer-specific price overrides.
Base Price: The primary sales price is determined by searching the item's pricing matrix for a price associated with the
ConnectorSettings.BasePriceLevelNameandConnectorSettings.DefaultSalesPriceCurrency. If no exact match is found, it falls back to a price with no specific price level for the default currency.Tier/Quantity Pricing: NetSuite's quantity-based pricing (where
quantity > 1) is mapped to App4SalesStafflePriceentities.Customer Pricing Groups: NetSuite customer pricing groups (defined in
ItemPriceDataOnCustomer.GroupPricingList) can override the default price level for specific items for a given customer. This allows for customer-segment-specific pricing.Customer-Specific Item Prices: Individual item prices for a specific customer can be explicitly defined in NetSuite (via
ItemPriceDataOnCustomer.ItemPricingList). These prices take precedence over general price levels and pricing groups for that particular item and customer. These can be direct price overrides or point to a different price level for that item for the specific customer.VAT Calculation: The item's VAT percentage is determined first by its NetSuite
taxSchedulename, matched against an internal VAT percentage configuration. If not found, a defaultConnectorSettings.ItemVatPercentageis used.
Image Handling
The connector retrieves item images from NetSuite and stores them in App4Sales.
Image Sources: Images can be retrieved from the item's standard
storeDisplayImagefield or from a custom field specified byConnectorSettings.CustomFieldForItemPicture.Image Retrieval: The connector fetches URLs for images from NetSuite
Filerecords and then downloads the image data (bytes).Image Storage: Downloaded images are stored in App4Sales as byte arrays, with duplicate checks to ensure efficiency.
Stock & Availability
Stock information is crucial for App4Sales and is handled with various configurations.
Locations/Warehouses: Stock can be managed across multiple NetSuite locations. These locations are mapped to App4Sales warehouses.
Stock Quantities: The connector synchronizes various stock quantities: available, committed, on hand, on backorder, and on order.
"To Be Received" Stock: A dedicated custom field in NetSuite (specified by
ConnectorSettings.ToBeReceivedStockCustomFieldName) can be used to capture and synchronize stock that is expected to be received.Zero/Negative Stock: Items with zero or negative stock are generally included, but specific filters can be applied to exclude them if needed (not explicitly shown in current code but possible through custom field filtering).
Matrix & Attributes
The connector supports NetSuite matrix items and maps various item attributes to App4Sales Item Categories and Free Fields.
Matrix Items: Parent matrix items are skipped, and only child variants are synchronized. The connector builds its own representation of the matrix by setting
MatrixXValue,MatrixXDescription,MatrixYValue,MatrixYDescription,MatrixParent, andMatrixParentIdbased on the item'smatrixOptionListand parent information, as configured byConnectorSettings.MatrixXFieldandConnectorSettings.MatrixYField.Item Categories: The following NetSuite fields are mapped to App4Sales Item Categories for filtering and categorization:
Product group (from
[email protected])Department (from
item.department?.name, ifConnectorSettings.UseDepartmentAsItemCategoryis enabled)Price group (from
item.pricingGroup?.name)Custom fields (all custom fields are added as categories using "[CustomField] {scriptId}")
Matrix options (all matrix options are added as categories using "[MatrixOption] {scriptId}")
Matrix parent name (using "[MatrixParent]")
Detailed store description (from
item.storeDetailedDescription)Weight (combining
item.weightanditem.weightUnit, e.g., "10.50 kg")
Free Fields: App4Sales Free Fields provide a flexible way to store additional item attributes. The connector can map:
Shift prices (tier prices with quantity > 1) if
ConnectorSettings.UseShiftPricesAsFreeFieldsis enabled.Pick locations (from
item.location?.name) ifConnectorSettings.UsePickLocationsAsFreeFieldsis enabled.Recommended retail price (from
SalesPrice) ifConnectorSettings.UseBasePriceAsFreeFieldis enabled.
Related Settings & Prerequisites
ItemTypesForSync: (String, comma-separated list) Specifies which NetSuite item record types (e.g., "InventoryItem", "AssemblyItem") should be synchronized. If empty, defaults to "InventoryItem".SyncItemsBasedOnCustomYesNoField: (String) The script ID of a NetSuite custom "Yes/No" field. If provided, only items where this field is set to "Yes" will be synchronized. This setting overridesItemTypesForSync.LocationsUsedForStock: (String, semicolon-separated list) Specifies the NetSuite location names (or internal IDs) to consider when retrieving stock data.RetrieveStockDataUsingServlets: (Boolean) If true, stock data will be retrieved from a custom NetSuite servlet instead of directly from item availability records.StockDataPropertiesMapping: (String, comma-separated) Required ifRetrieveStockDataUsingServletsis true. Defines the JSON property names for quantity, on-hand quantity, and delivery date within the servlet's response (e.g., "quantity,onHand,deliveryDate").RetrieveServletsStockDataScriptValue: (String) The script ID of the NetSuite servlet that provides stock data.RetrieveServletsStockDataDeployValue: (String) The deployment ID of the NetSuite servlet that provides stock data.BasePriceLevelName: (String) The name of the NetSuite price level to use as the base or default price level for items.DefaultSalesPriceCurrency: (String) The currency name (e.g., "Euro", "US Dollar") used to determine the default sales price.ToBeReceivedStockCustomFieldName: (String) The script ID of a NetSuite custom field that holds the "To Be Received" stock quantity.CustomFieldForItemPicture: (String) The script ID of a NetSuite custom field that contains an alternative item picture.UseStoreDisplayNameAsDescription: (Boolean) If true, the item'sstoreDisplayNameis used for the main App4Sales description; otherwise,salesDescriptionis used.UseDepartmentAsItemCategory: (Boolean) If true, the item's department in NetSuite is mapped as an App4Sales Item Category.ItemVatPercentage: (Decimal) The default VAT percentage to use if no specific tax schedule mapping is found.GetMinimumQuantityAsPPS: (Boolean) If true, the item'sminimumQuantityfrom NetSuite is used for App4SalesPurchasePackageSize.CustomFieldForPurchasePackageSize: (String) The script ID of a NetSuite custom field to use forPurchasePackageSizeifGetMinimumQuantityAsPPSis false.ItemStatusCustomFieldName: (String) The script ID of a NetSuite custom field that determines the item's status (e.g., "Pre-sale", "In Stock").ItemStatusCustomValuesMapping: (JSON String) A JSON mapping to translate NetSuite custom field status values to App4Sales item status values. Example:[{"NetSuiteStatus":"Presale","App4SalesStatus":"Presale"}].MatrixXField: (String, Regex) A regular expression pattern to identify the NetSuite custom field script ID that represents the X-axis of a matrix item.MatrixYField: (String, Regex) A regular expression pattern to identify the NetSuite custom field script ID that represents the Y-axis of a matrix item.ItemsDescriptionsMapping: (JSON String) A JSON array defining mappings from NetSuite item fields (NetSuiteItemFieldName) or custom fields (NetSuiteItemCustomFieldName) to App4Sales item description fields (A4SDescriptionFieldNumber, 2-5).ItemFieldsMapping: (JSON String) A JSON array defining mappings from NetSuite item fields (NetSuiteItemFieldName) or custom fields (NetSuiteItemCustomFieldName) to other App4Sales item fields (A4SItemFieldName) or Item Categories (A4SItemCategoryName).UseShiftPricesAsFreeFields: (Boolean) If true, NetSuite tier prices (shift prices) are added as free fields to the App4Sales item.UsePickLocationsAsFreeFields: (Boolean) If true, the item's pick location from NetSuite is added as a free field.UseBasePriceAsFreeField: (Boolean) If true, the item's calculated sales price is added as a free field named "Recommended retail price".DownloadPicturesConcurrencyLimit: (Integer) The maximum number of concurrent connections to use when downloading item pictures.PageSizeForBatchCalls: (Integer) The number of records to fetch in each batch when making paginated API calls to NetSuite.
Known Limitations
The connector explicitly skips NetSuite parent matrix items, processing only their child variants. This means that parent items are not available as standalone products in App4Sales.
The accuracy of stock data from servlets is dependent on the custom NetSuite script's implementation and adherence to the defined
StockDataPropertiesMapping.