Skip to main content

VismaNET - Create customer

Visma.NET Connector - Customer Creation/Update Overview This document details how the App4Sales Visma.NET connector creates or updates cu...

Updated over a week ago

Visma.NET Connector - Customer Creation/Update

Overview

This document details how the App4Sales Visma.NET connector creates or updates customer records in the Visma.NET ERP system. The process is triggered when a new customer is created in App4Sales or an existing customer is modified. The connector determines if a customer is new or existing based on the presence of a Visma.NET Customer Code and performs either a POST (create) or PUT (update) operation against the Visma.NET API.

Trigger & Permissions

The customer creation/update flow is typically initiated from the App4Sales mobile application (for new customers) or via backoffice synchronization processes. The connector requires the EditCustomer permission (Constants.ConnectorInfoInternalIds.EditCustomer) to execute this command.

Authentication with Visma.NET is handled via OAuth 2.0. The connector can use "Visma Connect" authentication or an older flow with username/password configured in the App4Sales CMS. Access tokens are automatically managed and refreshed by the connector.

Data Source Configuration

The primary data source for customer creation/update is the App4Sales internal Customer object. This object contains all the necessary information for mapping to the Visma.NET customer structure. Connector-specific settings within the App4Sales CMS also influence how certain fields are mapped and defaulted.

  • Visma.NET API Base URL: Configured to VismaNETConstants.ApiRoutes.Apim.

  • Customer Creation Endpoint (POST): [Base URL]/v1/customer

  • Customer Update Endpoint (PUT): [Base URL]/v1/customer/{CustomerCode}

Payload Mapping - Visma.NET Customer

The App4Sales Customer object is transformed into a VismaNetPostCustomer object before being sent to the Visma.NET API.

App4Sales Field

Source Field (API/Excel/DB)

Logic/Notes

CustomerName

Name

Directly mapped.

ChamberOfCommerceCode

CorporateId

Directly mapped.

VatCode

VatRegistrationId

Directly mapped.

PaymentConditionCode

CreditTermsId

Mapped to the ID of the credit terms. Empty values are sent as null.

Price List (derived from UsesPriceField)

PriceClassId

Determined from customer.UsesPriceField. The price list code is extracted, and if it ends with the currency (e.g., "-EUR"), the currency part is removed. If the price list is not a customer-specific or base price list, its code is mapped to PriceClassId.

Price List Currency (derived from UsesPriceField)

CurrencyId

Determined from customer.UsesPriceField. If not available, it defaults to the value configured in settings.DefaultCurrencyForNewCustomers. Empty values are sent as null.

DynamicFreeFields (for Customer Class)

CustomerClassId

If customer.DynamicFreeFields contains a field named "CustomerClass", its value is used. Otherwise, it defaults to the value configured in settings.CustomerClassForNewCustomers. Empty values are sent as null.

VatLiable

VatZoneId

If customer.VatLiable is true, mapped to settings.TaxZoneVatLiable. Otherwise, mapped to settings.TaxZoneNotVatLiable. Empty values are sent as null.

CustomerCode

Number

For new customer creation, this field is explicitly set to null as Visma.NET assigns the customer number. For updates, the customer code is used in the URL route parameter.

Payload Mapping - Main Contact Person

The App4Sales MainContactPerson is mapped to the MainContact of the Visma.NET customer.

App4Sales Field

Source Field (API/Excel/DB)

Logic/Notes

MainContactPerson.FullName

MainContact.Attention

Directly mapped.

Name

MainContact.Name

Mapped from the main App4Sales Customer's Name property.

MainContactPerson.Email

MainContact.Email

Directly mapped.

MainContactPerson.Phonenumber

MainContact.Phone1

Directly mapped.

MainContactPerson.MobileNumber

MainContact.Phone2

Directly mapped.

Payload Mapping - Visit Address (to Main Address)

The App4Sales address with AddressType "Visit" is mapped to the MainAddress of the Visma.NET customer. Mapping only occurs if AddressLine1 is not empty.

App4Sales Field

Source Field (API/Excel/DB)

Logic/Notes

Addresses (Type: Visit).AddressLine1

MainAddress.AddressLine1

Directly mapped.

Addresses (Type: Visit).AddressLine2

MainAddress.AddressLine2

Directly mapped.

Addresses (Type: Visit).AddressLine3

MainAddress.AddressLine3

Directly mapped.

Addresses (Type: Visit).PostCode

MainAddress.PostalCode

Directly mapped.

Addresses (Type: Visit).City

MainAddress.City

Directly mapped.

Addresses (Type: Visit).Iso2

MainAddress.CountryId

Mapped to the 2-letter ISO country code. Empty values are sent as null.

Payload Mapping - Delivery Address

The App4Sales address with AddressType "Delivery" is mapped to the DeliveryAddress of the Visma.NET customer. Mapping only occurs if AddressLine1 is not empty.

App4Sales Field

Source Field (API/Excel/DB)

Logic/Notes

Addresses (Type: Delivery).AddressLine1

DeliveryAddress.AddressLine1

Directly mapped.

Addresses (Type: Delivery).AddressLine2

DeliveryAddress.AddressLine2

Directly mapped.

Addresses (Type: Delivery).AddressLine3

DeliveryAddress.AddressLine3

Directly mapped.

Addresses (Type: Delivery).PostCode

DeliveryAddress.PostalCode

Directly mapped.

Addresses (Type: Delivery).City

DeliveryAddress.City

Directly mapped.

Addresses (Type: Delivery).Iso2

DeliveryAddress.CountryId

Mapped to the 2-letter ISO country code. Empty values are sent as null.

Validation & Defaults

  • For new customers, VismaNetPostCustomer.Status defaults to Active.

  • Customer codes (VismaNetPostCustomer.Number) are not sent during creation/update, as Visma.NET assigns them.

  • CreditTermsId, CurrencyId, CustomerClassId, VatZoneId, and CountryId for addresses are sent as null if their corresponding App4Sales values are empty.

  • If customer.DynamicFreeFields does not contain a "CustomerClass" field, the CustomerClassId defaults to the value specified in the connector setting CustomerClassForNewCustomers.

  • If a price list's currency cannot be determined from customer.UsesPriceField, the CurrencyId defaults to settings.DefaultCurrencyForNewCustomers.

  • For addresses, mapping only occurs if AddressLine1 is not empty.

Response & Error Handling

  • Successful Creation (POST): Upon successful creation, the Visma.NET API returns a Location header containing the URI of the newly created customer. The connector extracts the customer's new code from this URI and assigns it to customer.CustomerCode in App4Sales. The updated customer record is then persisted in the App4Sales database via CustomerUpdateHandler().Update(customer).

  • Successful Update (PUT): Visma.NET PUT requests do not return a Location header. The connector assumes success if no error is returned.

  • Error Handling: If the Visma.NET API returns an error, a RestException is caught. The connector attempts to deserialize the error response to extract details such as ExceptionType, ExceptionMessage, and ExceptionFaultCode, logging these details. A generic "Unknown error occurred" or "Fatal exception occurred" message is used if specific error details cannot be retrieved. In case of an error, an Exception is thrown, halting the process.

  • Duplicate Detection: The connector detects existing customers by attempting to retrieve a VismaNetCustomer using customer.CustomerCode before attempting to create a new one. If a customer with the code is found, an update operation (PUT) is performed instead of a creation (POST).

Known Limitations

  • The InvoiceAddress, InvoiceContact, and DeliveryContact fields of VismaNetPostCustomer are not directly mapped from the App4Sales Customer object during a new customer creation; they appear to be populated only during an update if an existing Visma.NET customer record is provided.

  • The CreditLimit field of VismaNetPostCustomer is not explicitly mapped from the App4Sales Customer object. It is likely preserved from an existing Visma.NET customer during an update.

Did this answer your question?