Skip to main content

Visma - Create customer

Visma Connector - Create Customer This document details the process by which the App4Sales platform creates or updates customer records i...

Updated over a week ago

Visma Connector - Create Customer

This document details the process by which the App4Sales platform creates or updates customer records in the Visma ERP system via the AccountView connector. This process is initiated when a new customer is created or an existing customer is updated within App4Sales. The connector synchronizes core customer information, addresses, and contact details, ensuring consistency between App4Sales and Visma AccountView.

Trigger & Permissions

The customer creation/update flow is triggered by the OptA4SNewCustomers method within the App4Sales Visma connector. This functionality is enabled when the following connector info flags are active:

  • ConnectorInfoInternalIds.EditCustomer

  • ConnectorInfoInternalIds.CreateCustomer

Authentication to the Visma AccountView API is managed via an access token and company ID, which are configured in the connector settings and refreshed automatically as needed.

Data Source Configuration

Customer data originates from the App4Sales platform. The connector receives customer information in an XML format via an input stream (`request.inputStream`). This XML contains fields such as customer code, GUID, relation group, and search code. The connector then processes this data for submission to the Visma AccountView REST API.

Payload Mapping

The following tables detail the mapping of App4Sales customer fields to Visma AccountView API fields. Note that the App4Sales Customer object is first constructed from an AccountViewCustomer within the MapCustomer extension method, and then its properties are used to build the final API payload.

Core Customer Fields (Business Object: AR1 - Contact)

App4Sales Field

Source Field (Visma API)

Logic/Notes

CustomerCode

sub_nr

If empty for a new customer, a sequential number is generated starting from AccountViewCustomerCodeStartingNumber setting.

CustomerName

acct_name

Directly mapped.

Discount

disc_pct

Value of customer.Discount.Value converted to an integer string.

LanguageCode

lng_code

Mapped using MappedLanguagesContext.Instance.FindMappedLanguageByLanguageCodeForNewCustomer(customer.LanguageCode).

VatCode

vat_nr

Mapped from accountViewCustomer.VatNr.

VatLiable

(Not a direct field)

Determined by CheckVatLiable method based on accountViewCustomer.VatCode, connector settings CustomerVatLiableCodes, VatLiableWhenVatCodeIsEmpty, and NoVatLiableCodes.

PaymentConditionCode

disc_code

Mapped from accountViewCustomer.PaymentCondition, with empty strings converted to null.

ChamberOfCommerceCode

coc_code

Directly mapped from accountViewCustomer.ChamberOfCommerce.

CustomerManager

emp_nr

Directly mapped from accountViewCustomer.EmployeeNumber. If UseUsernameAsEmployeeForNewCustomer setting is enabled, this can be overridden by the request.username.

Phone

tel_bus

Directly mapped from accountViewCustomer.PhoneNumber.

MobileNumber

tel_mob

Directly mapped from accountViewCustomer.MobileNumber.

Currency

cur_code

Directly mapped from accountViewCustomer.CurrencyCode.

CountryCode

cnt_code

Mapped from customer.Addresses[0].Iso2.

SearchCode

SRC_CODE

If not provided in the input stream, it defaults to the first 4 characters of CustomerName converted to uppercase.

RelationGroup

RPL_GRP

Directly mapped if present in the input stream.

UsesPriceField

APX_LIST

Determined by GetPriceListId method based on accountViewCustomer.PriceList and connector settings. If PriceListsBasedOnItemFields is true, maps to an integer (1-4). Otherwise, uses the hash code of the price list code. Falls back to the first available price list if no match is found.

ERP Identifier

(Visma PrimaryKey)

After successful creation, the PrimaryKey returned by Visma is stored as the CustomerCode in the App4Sales database.

CollectionAccountCode

acct_nr

Value from Settings.CollectionAccountCodeForNewCustomer if specified.

Address Fields (Included within AR1 - Contact)

Both a visit address ("VIS") and a delivery address ("DEL") are generated from the source data. The connector prioritizes these based on the SwapDeliveryAndVisitAddress setting.

App4Sales Field

Source Field (Visma API)

Logic/Notes

AddressLine1

address1

Mapped from accountViewCustomer.Street. The SwapDeliveryAndVisitAddress setting determines if the visit or delivery address is used for address1.

PostCode

post_code

Mapped from accountViewCustomer.Postcode.

City

city

Mapped from accountViewCustomer.City.

Fax

FAX_BUS

Mapped from accountViewCustomer.Fax.

Contact Person Fields (Business Object: PP1 - People, then linked to AR1 - Contact)

If SendContactAsAdministrationContact or SendContactAsMainContact settings are enabled, a separate request is made to create/update a contact person in Visma AccountView before linking it to the customer. The contact person details are taken from the first contact person in the App4Sales customer object (customer.ContactPersons[0]).

App4Sales Field

Source Field (Visma API)

Logic/Notes

ContactId

pp_code

If empty for a new contact, a sequential number is generated starting from AccountViewContactCodeStartingNumber setting.

FirstName

fst_name

Directly mapped.

LastName

lst_name

Directly mapped.

FullName

dsp_name

If accountViewCustomer.MainContactID is not empty, uses accountViewCustomer.MainContact; otherwise, uses accountViewCustomer.AdminContact.

Email

mail_bus

Directly mapped.

Phonenumber

tel_bus

Directly mapped.

MobileNumber

tel_mob

Directly mapped.

Visma PrimaryKey (from PP1)

main_pp / admin_pp

If SendContactAsMainContact or SendContactAsAdministrationContact is enabled, the PrimaryKey of the created/updated contact person (from the PP1 response) is linked to the customer in the AR1 request.

Dynamic and Free Fields

App4Sales Field

Source Field

Logic/Notes

DynamicFreeFields

AccountViewCustomer properties

Custom fields "SearchCode" and "RelationGroup" from the AccountViewCustomer are serialized into XML format for DynamicFreeFields.

FreeFields

AccountViewCustomer properties

Includes "PriceList" and "PriceListPercentage" from the AccountViewCustomer, serialized into XML format.

Validation & Defaults

  • **Customer Existence:** The connector first attempts to retrieve a customer using the provided customerguid. If no customer is found, and customerCode is empty, it proceeds with creating a new customer.

  • **Code Generation:** For new customers, if customerCode is empty, a unique customer code is generated starting from the value in the AccountViewCustomerCodeStartingNumber setting (defaulting to 500000 if not set). Similarly, for new contact persons, a contactId is generated using AccountViewContactCodeStartingNumber (defaulting to 500000).

  • **Search Code Default:** If searchCode is not provided in the input, it defaults to the first four characters of the CustomerName, converted to uppercase.

  • **VAT Liability:** The CheckVatLiable method determines if a customer is VAT liable based on the VatCode, a list of VAT liable codes (CustomerVatLiableCodes setting), and whether a customer is considered VAT liable when their VAT code is empty (VatLiableWhenVatCodeIsEmpty setting). Specific VAT codes can also be marked as non-liable using the NoVatLiableCodes setting.

  • **Price List Default:** If the `PriceListCode` from AccountViewCustomer does not match any configured price lists, the connector attempts to use the first available price list.

  • **Address Handling:** If address lines, postcode, or city are missing for either the visit or delivery address, empty strings are sent to the ERP.

Response & Error Handling

  • **API Responses:** The connector expects JSON responses from the AccountView API. Responses are deserialized into AccountViewContactResponse objects.

  • **Customer Code Update:** Upon a successful customer creation in Visma AccountView, the ERP-assigned PrimaryKey (customer code) is retrieved from the API response and used to update the customerCode in the App4Sales database for the corresponding customer GUID.

  • **Error Logging:** API errors (non-OK HTTP status codes) are logged, including details from the AccountView API's error message.

  • **Exceptions:** If an API request fails, an exception is thrown, detailing the error.

  • **Return Value:** The method returns "ERROR: Customer could not be found in the database" if the initial customer retrieval fails, or "Succes: [New Customer PrimaryKey]" upon successful creation/update.

Special Logic & Filters

  • **Upsert Logic:** The connector implements an upsert (update or insert) mechanism. It first tries to find an existing customer by GUID. If found, it updates; otherwise, it creates a new customer.

  • **XML Input Parsing:** The incoming request stream is parsed as XML to extract key customer identifiers.

  • **Contact Person Update/Insert:** A contact person record (`PP1` business object) is created or updated separately if configured, and then linked to the main customer record (`AR1` business object).

  • **Address Swapping:** The SwapDeliveryAndVisitAddress setting allows the connector to swap the visit and delivery addresses when sending them to AccountView.

Related Settings & Prerequisites

The functionality of the Create Customer process is influenced by the following connector settings:

  • AccountViewCustomerCodeStartingNumber: The starting number for auto-generating customer codes.

  • AccountViewContactCodeStartingNumber: The starting number for auto-generating contact person IDs.

  • SendContactAsAdministrationContact: Boolean flag to determine if the contact person should be sent as the administration contact.

  • SendContactAsMainContact: Boolean flag to determine if the contact person should be sent as the main contact.

  • UseUsernameAsEmployeeForNewCustomer: Boolean flag to use the App4Sales username as the employee number for new customers in AccountView.

  • CollectionAccountCodeForNewCustomer: The collection account code to be assigned to new customers.

  • SwapDeliveryAndVisitAddress: Boolean flag to swap delivery and visit addresses when sending to AccountView.

  • SkipPriceLists: Boolean flag to skip retrieving price lists.

  • CustomerVatLiableCodes: Comma-separated list of VAT codes considered liable.

  • VatLiableWhenVatCodeIsEmpty: Boolean flag indicating if a customer is VAT liable when the VAT code is empty.

  • NoVatLiableCodes: Comma-separated list of VAT codes that are explicitly not considered liable.

  • PriceListsBasedOnItemFields: Boolean flag indicating if price lists are based on item fields.

  • PriceList1Code: Code for Price List 1.

  • PriceList2Code: Code for Price List 2.

  • PriceList3Code: Code for Price List 3.

  • PriceList4Code: Code for Price List 4.

Did this answer your question?