Skip to main content

VismaNET - Item sync

Visma.NET Connector - ItemUpdate This function synchronizes item data from Visma.NET to App4Sales. It retrieves item information, VA...

Updated over a week ago

Visma.NET Connector - ItemUpdate

This function synchronizes item data from Visma.NET to App4Sales. It retrieves item information, VAT details, unit of measure data, sales categories, and item attachments (images) from Visma.NET. The retrieved data is then transformed and mapped to App4Sales internal item structures, including item codes, descriptions, prices, VAT percentages, units, EAN codes, item classes, item categories, purchase package sizes, and stock amounts. Finally, it updates the App4Sales database with the processed item data, including item pictures.

Data Source Configuration

Item data is pulled from the Visma.NET API using the following endpoints and parameters:

  • VAT Information: Fetched from /v1/vat.

  • Inventory (Items): Fetched from /v1/inventory. Supports pagination with a page size of 500. Each item can be filtered by its status (Inactive or NoSales are skipped).

  • Unit of Measure: Fetched from /v1/unitofmeasure. Supports pagination with a page size of 500.

  • Sales Categories: Fetched from /v1/salescategory.

  • Sales Category Inventory: Fetched from /v1/salescategory/{categoryId}/item, where {categoryId} is the ID of a sales category.

  • Inventory Attachments (Images): Fetched from /v1/attachment/{attachmentId}, where {attachmentId} is the ID of an attachment associated with an item. Returns raw byte data.

  • Warehouses: Fetched from /v1/warehouse. Supports pagination with a page size of 500. Only active warehouses are considered.

  • Sales Order Types: Fetched from /v1/salesordertype. Supports pagination with a page size of 500. Only active sales order types are processed.

Authentication is handled via OAuth2 (Visma Connect) or an older username/password flow, depending on connector settings.

Data Mapping Table: Item

App4Sales Field

Source Field (API/Excel/DB)

Logic/Notes

ItemCode

VismaNetInventory.InventoryNumber

Directly mapped from the Visma.NET inventory number.

InternalItemCode

VismaNetInventory.InventoryId

Mapped from the Visma.NET inventory ID, converted to string.

Description

VismaNetInventory.Description

Directly mapped from the Visma.NET item description.

SalesPrice

VismaNetInventory.DefaultPrice

Directly mapped from the Visma.NET default price.

VatIncluded

Hardcoded

Hardcoded to 'E'.

VatPercentage

VismaNetVat.Schedules.VatRate

Derived from VismaNetVat data. Matches VismaNetVat.Zones with ConnectorSettings.DefaultVatCodeForItems and VismaNetVat.Categories with VismaNetInventory.VatCode.Id. The VatRate from the latest schedule is used.

Unit

VismaNetInventory.SalesUnit

Directly mapped from the Visma.NET sales unit.

EanCode

VismaNetInventory.CrossReferences.AlternateId

Extracted from VismaNetInventory.CrossReferences where AlternateType is 'Barcode'.

ItemStatus

VismaNetInventory.Attributes.Value or VismaNetInventory.GetUnknownElement()

If ConnectorSettings.CustomItemFieldForTheItemStatus is configured, attempts to retrieve item status from a custom field in VismaNetInventory.Attributes or an unknown element. Value is validated against App4Sales' available item statuses.

ItemClasses

VismaNetInventory.PostingClass.Description, VismaNetInventory.ItemClass.Description, VismaNetSalesCategory.Description

  • A 'Filter' item class (-667) is created from VismaNetInventory.PostingClass.Description.

  • An 'Item class' (-669) is created from VismaNetInventory.ItemClass.Description.

  • Sales categories are mapped as item classes. The sales category name (VismaNetSalesCategory.Description) becomes the item class value. The parent sales category name (if exists) becomes the item class description, otherwise 'Sales category' (-668) is used.

ItemCategories

VismaNetInventory.Attributes

Derived from VismaNetInventory.Attributes. If ConnectorSettings.OnlyUseAttributeDescriptionForItemCategories is true, the item category name is derived from Attribute.Description (fallback to Attribute.Value). Otherwise, it is derived from Attribute.Value concatenated with Attribute.Description.

PurchasePackageSize

VismaNetUnitOfMeasure.UnitRate or VismaNetInventory.Attributes.Value

First, determined from VismaNetUnitOfMeasure.UnitRate by matching the sales, purchase, or base unit of the inventory item (controlled by ConnectorSettings.UnitFieldForPackageSize).
Can be overridden if ConnectorSettings.PurchasePackageSizeAttribute is set, by taking the value from VismaNetInventory.Attributes that matches the configured attribute ID.

LastAvailableStock

VismaNetInventory.WarehouseDetails.AvailableForShipment or VismaNetInventorySummary.AvailableForShipment

If ConnectorSettings.SyncDetailedStockInformation is enabled, stock is retrieved via an additional live call (GetStockForItemsCommand) and uses VismaNetInventorySummary.AvailableForShipment.
Otherwise, it is calculated as the sum of AvailableForShipment from VismaNetInventory.WarehouseDetails. If ConnectorSettings.Warehouse is specified, only warehouses matching this setting are included in the sum.

Data Mapping Table: Item Pictures

App4Sales Field

Source Field (API/Excel/DB)

Logic/Notes

ItemPicture.Hash

VismaNetInventoryAttachment (raw bytes)

A SHA1 hash is generated from the raw bytes of the attachment.

ItemPicture.PictureBytes

VismaNetInventoryAttachment (raw bytes)

Raw bytes of the attachment. Only stored if the hash is new (not existing in App4Sales).

ItemPicture.Source

Hardcoded

Hardcoded to 'ERP'.

ItemPictureLink.Hash

VismaNetInventoryAttachment (raw bytes)

A SHA1 hash is generated from the raw bytes of the attachment.

ItemPictureLink.Sequence

VismaNetInventoryAttachment (ordered)

Determined by the order of attachments, sorted by name, starting from 1.

ItemPictureLink.ItemCode

VismaNetInventory.InventoryNumber

Links the picture to the item using the item's inventory number.

Special Logic & Filters

  • Item Filtering: Items with VismaNetInventoryStatus as 'Inactive' or 'NoSales' are skipped.

  • Order Type Synchronization: The connector attempts to add Visma.NET sales order types to App4Sales. If a 'SO' (SalesOrder) type exists in Visma.NET, it's mapped to the App4Sales 'Order' type. Other active Visma.NET sales order types are added as new order types in App4Sales if they don't already exist, with SendToBackoffice set to true and OnRelationCard set to false. This occurs at the beginning of the ItemUpdate process.

  • Warehouse Synchronization: Active warehouses from Visma.NET are retrieved and updated in App4Sales. This happens at the end of the ItemUpdate process.

  • Image Synchronization:

    • Images are synchronized only if ConnectorSettings.DontSyncErpAttachments is false AND PimSettings.UseImagesOnlyFromPIM is false.

    • Attachments are retrieved as raw bytes. A hash is generated for each attachment.

    • If an attachment's hash already exists in App4Sales, only a link to the existing image is created. Otherwise, the raw image bytes are stored along with the link.

    • Attachments are sorted by name for consistent sequencing.

  • Stock Synchronization:

    • If ConnectorSettings.SyncDetailedStockInformation is true, a separate API call is made to retrieve detailed stock information for each item.

    • If ConnectorSettings.SyncDetailedStockInformation is false, stock is aggregated from VismaNetInventory.WarehouseDetails.

Domain Specifics (Expanded)

Price Logic

The base sales price for an item is directly sourced from VismaNetInventory.DefaultPrice. VAT percentage is dynamically determined based on the connector settings (DefaultVatCodeForItems) and the item's VAT code. The system hardcodes 'E' for VatIncluded. No tier/volume pricing rules, quantity breaks, or customer-specific price lists are explicitly handled in this update function.

Image Handling

Item images are sourced directly from item attachments within Visma.NET. The system retrieves all attachments associated with an inventory item. Each attachment is treated as an image, and its raw bytes are fetched from the /v1/attachment/{attachmentId} endpoint. The attachments are sorted alphabetically by name before processing. A SHA1 hash is generated from the image's raw bytes, which is used to prevent duplicate storage in App4Sales if the exact image (based on its hash) already exists. Images are linked to items using their ItemCode.

Stock & Availability

Stock information is updated in App4Sales based on configuration. If detailed stock synchronization is enabled (ConnectorSettings.SyncDetailedStockInformation is true), a live API call is made for each item to retrieve comprehensive stock values, including AvailableForShipment, which populates LastAvailableStock in App4Sales. Otherwise, LastAvailableStock is calculated by summing the AvailableForShipment values from each of the item's warehouse details (VismaNetInventory.WarehouseDetails). If a ConnectorSettings.Warehouse is specified, stock is only considered from those designated warehouses.

Matrix & Attributes

Item classes are derived from Visma.NET's posting classes, item classes, and sales categories. Posting classes and item classes from Visma.NET are mapped to generic 'Filter' and 'Item class' categories in App4Sales, respectively. Sales categories from Visma.NET are also mapped to item classes in App4Sales, using their names as values and their parent category names (or a default 'Sales category' label) as descriptions.

Item categories in App4Sales are populated from VismaNetInventory.Attributes. The exact mapping depends on the ConnectorSettings.OnlyUseAttributeDescriptionForItemCategories setting. No explicit matrix item (parent/child variant) handling or linking logic is present within this specific ItemUpdate function.

Related Settings & Prerequisites

  • DefaultVatCodeForItems: Used to determine the VAT percentage for items by matching against Visma.NET VAT zones.

  • CustomItemFieldForTheItemStatus: Specifies a custom field in Visma.NET inventory attributes or unknown elements to use for setting the item status in App4Sales.

  • UnitFieldForPackageSize: Determines whether the sales, purchase, or base unit of measure should be used to calculate PurchasePackageSize.

  • PurchasePackageSizeAttribute: An optional setting that, if configured, overrides the calculated PurchasePackageSize with a value from a specific inventory attribute.

  • DontSyncErpAttachments: If true, item attachments (images) from Visma.NET will not be synchronized.

  • PimSettings.UseImagesOnlyFromPIM: If true, item attachments (images) from Visma.NET will not be synchronized, as images are expected to be managed by a Product Information Management (PIM) system.

  • SyncDetailedStockInformation: If true, detailed stock information for each item is retrieved via a live API call; otherwise, it's aggregated from warehouse details.

  • Warehouse: A comma- or semicolon-separated list of warehouses. If specified, stock calculations will only consider these warehouses.

Known Limitations

The ItemUpdate function does not explicitly handle matrix item (parent/child variant) relationships, such as linking parent items to their variants or synchronizing variant-specific data. All items are processed individually based on their VismaNetInventory entry.

Price logic is limited to the default sales price. Advanced pricing features like tier pricing, volume discounts, or customer-specific price lists are not implemented within this update mechanism.

The system assumes that the /v1/inventory endpoint, when called without specific item IDs, returns a list of all inventory items. The RouteInfoProvider's current definition for VismaNetInventory (v1/inventory/{0}) primarily suggests fetching a single item by ID, which could lead to unexpected behavior if this assumption is incorrect.

Did this answer your question?