Skip to main content

ExactOnlinePremium - Create customer

ExactOnlinePremium Connector - Create Customer This document describes the customer creation and update process within the ExactOnlinePrem...

Updated over a week ago

ExactOnlinePremium Connector - Create Customer

This document describes the customer creation and update process within the ExactOnlinePremium connector. This function handles incoming customer data from App4Sales, transforms it into an Exact Online customer entity, and either creates a new customer or updates an existing one in Exact Online. It also manages associated contact persons and addresses.

3. Data Source Configuration

The customer data originates from an InternalRequest object. This object encapsulates the incoming payload from App4Sales, typically containing customer information in an XML format. The connector extracts customer entities from this request using the XMLParserObj.GetCustomersFromRequest(request) method.

Trigger & Permissions

This customer creation/update process is triggered when a new customer is created or an existing customer is edited within the App4Sales platform. The functionality is enabled by the following connector info flags:

  • Core.Constants.ConnectorInfoInternalIds.EditCustomer

  • Core.Constants.ConnectorInfoInternalIds.CreateCustomer

Payload Mapping

The connector transforms the incoming XmlCustomer object (parsed from the App4Sales request) into an ExactOnlineCustomerUpdate entity. The following table details the mapping of fields:

App4Sales Field (XmlCustomer)

Source Field (ExactOnlineCustomerUpdate)

Logic/Notes

CustomerGuid

ID

Direct mapping.

CustomerName

Name

Direct mapping.

CustomerCode

Code

If CustomerCode is empty, it defaults to null.

-

Blocked

Hardcoded to false.

ChamberOfCommerceCode

ChamberOfCommerce

Direct mapping.

Discount

DiscountSales

If Discount is empty, defaults to 0. Otherwise, parsed as decimal and divided by 100.

Email

Email

Direct mapping.

Fax

Fax

Direct mapping.

-

IsSales

Hardcoded to true.

-

IsReseller

Maps to settings.OnlyLoadDealers.

LanguageCode

Language

If present, converted to uppercase.

PaymentCondition

PaymentConditionSales

If PaymentCondition is empty, defaults to null.

Phone

Phone

Direct mapping.

VatCode

VATNumber

If VatCode is empty, defaults to null.

VatLiable

VATLiability

Mapped to "L" if VatLiable is true AND settings.VatLiabilityBasedOnVatRegime is true, otherwise null.

VatLiable, CountryCode

SalesVATCode

Determined by the GetSalesVatCode helper method, considering VatLiable, CountryCode, and connector settings.

-

Status

Hardcoded to "C" (Active).

VisitAddress1

AddressLine1

Direct mapping.

VisitAddress2

AddressLine2

Direct mapping.

VisitCity

City

Direct mapping.

CountryCode

Country

Direct mapping.

VisitPostCode

Postcode

Direct mapping.

UsesPrice (via GetPriceListId)

PriceList

Determined by GetPriceListId based on UsesPrice and connector settings (PriceList2Id, PriceList3Id, PriceList4Id). If resulting GUID is empty, defaults to null.

UsesPrice (via PriceListsContext.Instance.GetCurrencyByPriceListId)

SalesCurrency

Determined by currency parameter or derived from UsesPrice via PriceListsContext.

MainContactId (parameter)

MainContact

Passed as a parameter to the ConvertToEntity method.

-

Created

Hardcoded to DateTime.Now.

-

Classification1

Hardcoded to null.

accountManager (parameter)

AccountManager

Mapped to accountManager.UserID if accountManager is provided.

accountManager (parameter)

AccountManagerFullName

Mapped to accountManager.FullName if accountManager is provided.

Website

Website

Direct mapping.

-

StartDate

Hardcoded to DateTime.Now.

-

EndDate

Hardcoded to null.

Custom Fields

Additional custom fields can be mapped from the XmlCustomer.UnknownElements to the ExactOnlineCustomerUpdate entity based on the settings.CustomCustomerFieldsMapping. Each entry in CustomCustomerFieldsMapping specifies an XmlName and a PropertyName. If an element with the XmlName exists in XmlCustomer.UnknownElements and the object name is 'customer', its value is added to restRequest.AddUnknownElement with the specified PropertyName.

Validation & Defaults

  • GL Account Sales: The GLAccountSales field in Exact Online is populated from the connector setting Settings.GLAccountSalesCode.

  • GLAR (Accounts Receivable): The GLAR field in Exact Online is populated from the connector setting Settings.GLAccountGLARCode.

  • Price List ID: The priceListId is determined by parsing the UsesPrice field from the incoming XmlCustomer. If UsesPrice is '2', '3', or '4', the corresponding PriceList ID (PriceList2Id, PriceList3Id, or PriceList4Id) from the connector settings is used. If parsing fails or the value is not '2', '3', or '4', it defaults to Guid.Empty.

  • Currency: The SalesCurrency is determined by a passed currency parameter or derived from the UsesPrice field using PriceListsContext.Instance.GetCurrencyByPriceListId.

Response & Error Handling

After attempting to create or update a customer in Exact Online, the connector processes the response as follows:

  • Successful Creation: If a new customer is successfully created, Exact Online returns a customer code. This code is then used to update the corresponding customer entry in the App4Sales database. Duplicate customer codes in the App4Sales database are handled by prefixing the existing code with "D" before updating.

  • Successful Update: If an existing customer is successfully updated, the connector confirms the update and uses the existing customer code.

  • REST API Errors (RestException): If the Exact Online API returns an error, a RestException is caught. The error response content is deserialized to extract a user-friendly error message, which is then logged and returned to App4Sales, prefixed with ERROR:.

Special Logic & Filters

  • Upsert Logic: The connector intelligently handles customer creation and updates. If the incoming XmlCustomer object has an empty CustomerCode, it is treated as a new customer and a POST request is made to Exact Online. If a CustomerCode is present, it's considered an existing customer, and a PUT request is issued to update the existing record.

  • Duplicate Customer Code Handling: When a new customer is created, and the assigned customer code from Exact Online already exists in the App4Sales database, the existing App4Sales customer's code is prefixed with "D" to avoid conflicts, ensuring Exact Online remains the leading system for customer codes.

  • Contact Person Management: After processing the main customer entity, the connector attempts to create or update the main contact person associated with the customer.

    • It first checks for an existing contact person ID in the App4Sales database.

    • If no ID is found, a new GUID is generated, the XmlCustomer is converted to an ExactOnlineContactPersonUpdate, and a POST request is made to Exact Online. Custom fields with ObjectName 'contact' are also applied. The newly obtained Exact Online contact ID is then stored in the App4Sales database.

    • If a contact ID exists, the XmlCustomer is converted, custom fields are applied, and a PUT request is used to update the existing contact person in Exact Online.

  • Delivery Address Management: The connector also manages the customer's delivery address.

    • If both DeliveryAddress1 and DeliveryPostCode are empty in the incoming XmlCustomer, no delivery address processing occurs.

    • It checks for an existing main delivery address in Exact Online for the customer.

    • The XmlCustomer data is converted into an ExactOnlineAddressUpdate object, and custom fields with ObjectName 'address' are applied.

    • Based on whether an existing address was found, a POST (new) or PUT (update) request is made to Exact Online. The address ID in App4Sales is then updated.

  • Invoice Address Management: If the incoming XmlCustomer contains invoice address information (checked via c.UnknownElements.ContainsKey(Constants.InvoiceAddress1)),

    • The connector first checks if a main invoice address already exists in Exact Online for the customer.

    • The XmlCustomer data is converted into an ExactOnlineAddressUpdate specifically for the invoice address. If no invoice address data is available for conversion, this step is skipped.

    • Similar to delivery addresses, a POST or PUT request is made to Exact Online to create or update the invoice address.

Custom Fields

Additional custom fields can be mapped from the XmlCustomer.UnknownElements to the ExactOnlineCustomerUpdate entity based on the settings.CustomCustomerFieldsMapping. Each entry in CustomCustomerFieldsMapping specifies an XmlName and a PropertyName. If an element with the XmlName exists in XmlCustomer.UnknownElements and the object name is 'customer', its value is added to restRequest.AddUnknownElement with the specified PropertyName.

Related Settings & Prerequisites

The behavior of the customer creation/update process is influenced by the following connector settings:

  • CustomCustomerFieldsMapping: Defines how custom fields from the incoming App4Sales request (XmlCustomer.UnknownElements) are mapped to the Exact Online customer, contact person, and address entities.

  • GenerateCurrencyPriceLists: (Boolean) If enabled, the connector attempts to determine the customer's currency based on their price list.

  • GLAccountSalesCode: Specifies the GL Account for Sales to be used for new or updated customers in Exact Online.

  • GLAccountGLARCode: Specifies the GLAR (General Ledger Accounts Receivable) to be used for new or updated customers in Exact Online.

  • OnlyLoadDealers: (Boolean) If enabled, new customers are marked as resellers in Exact Online.

  • VatLiabilityBasedOnVatRegime: (Boolean) If enabled, the VAT Liability in Exact Online is set to 'L' (Liable) based on the customer's VatLiable status.

  • PriceList2Id, PriceList3Id, PriceList4Id: GUIDs for specific price lists in Exact Online. These are used when the incoming customer's UsesPrice field corresponds to '2', '3', or '4' respectively, to assign the correct price list to the customer.

  • VatCodeBasedOnCountryCode: Specifies a country code. Used in conjunction with UseVatLiabilityForDefaultCountry to determine the Sales VAT Code.

  • UseVatLiabilityForDefaultCountry: (Boolean) If enabled, and the customer's country matches VatCodeBasedOnCountryCode, then VatLiableCode is used as the Sales VAT Code. Otherwise, NotVatLiableCode or NotVatLiableCodeOutsideEU is used.

  • VatLiableCode: The VAT code to use when the customer is VAT liable, or when UseVatLiabilityForDefaultCountry is enabled and the country matches VatCodeBasedOnCountryCode.

  • NotVatLiableCode: The VAT code to use when the customer is not VAT liable and is within the EU.

  • NotVatLiableCodeOutsideEU: The VAT code to use when the customer is not VAT liable and is outside the EU. If empty, NotVatLiableCode is used as a fallback.

  • UpdateEmailOnlyForCustomer: (Boolean) If enabled, email addresses are not updated for contact persons or delivery addresses.

  • UpdatePhoneOnlyForCustomer: (Boolean) If enabled, phone numbers are not updated for contact persons or delivery addresses.

  • SendHouseNumberAndAdditionSeperate: (Boolean) If enabled, the street, house number, and addition from an address are sent as separate fields (AddressLine1, AddressLine2, AddressLine3) to Exact Online.

Did this answer your question?