Skip to main content

Uniconta - Customer sync

Uniconta Connector - Customer Update This document describes the customer update process for the Uniconta connector, detailing how custo...

Updated over a week ago

Uniconta Connector - Customer Update

This document describes the customer update process for the Uniconta connector, detailing how customer information is synchronized between Uniconta and the App4Sales platform. It covers both the retrieval of customer data from Uniconta into App4Sales and the sending of customer data from App4Sales to Uniconta. The synchronization includes core customer fields, addresses, contact persons, custom free fields, and associated price lists.

Data Source Configuration

The Uniconta connector connects to the Uniconta API. The following settings are used for authentication and environment selection:

  • Uniconta API Key: Used to authenticate with the Uniconta API.

  • Uniconta Username: The username for accessing Uniconta. If not specified in the administration session, a global setting is used.

  • Uniconta Password: The password for the Uniconta username. If not specified in the administration session, a global setting is used.

  • Company ID: The specific Uniconta company to connect to.

Data is pulled from Uniconta and pushed to Uniconta using the configured API credentials.

Data Mapping - App4Sales Customer (from Uniconta DebtorClient)

App4Sales Field

Source Field (API/Excel/DB)

Logic/Notes

CustomerCode

unicontaCustomer._Account

Direct mapping of the Uniconta account number.

CustomerName

unicontaCustomer._Name

Direct mapping of the Uniconta customer name.

Discount

unicontaCustomer._LineDiscountPct / unicontaCustomer._EndDiscountPct

If 'UseLineDiscountPctInsteadOfEndDiscountPct' setting is true, uses _LineDiscountPct; otherwise, uses _EndDiscountPct. Cast to decimal.

VatLiable

unicontaCustomer._Vat

True if _Vat field is not null or empty.

Website

unicontaCustomer._Www

Direct mapping of the Uniconta website.

Phone

unicontaCustomer._MobilPhone

Direct mapping of the Uniconta mobile phone.

Email

unicontaCustomer._ContactEmail

Direct mapping of the Uniconta contact email.

VatCode

unicontaCustomer._LegalIdent

Direct mapping of the Uniconta legal identifier.

PaymentConditionCode

unicontaCustomer._Payment

Direct mapping of the Uniconta payment condition.

InternalCode

unicontaCustomer.RowId.ToString()

The Uniconta internal row ID, converted to string.

Currency

unicontaCustomer._Currency

Uniconta currency code, converted to string. If Uniconta currency is 'XXX', then it's mapped to an empty string.

Sysmodified

unicontaCustomer.UpdatedAt

Last update timestamp from Uniconta.

LanguageCode

unicontaCustomer._Language.ToString()

Uniconta language code, converted to string.

CustomerManager

employees?.FirstOrDefault(x => x.Number == unicontaCustomer._Employee)?.Name

The name of the employee (customer manager) in Uniconta, based on the employee number.

UsesPriceField

customerPriceList?.Id

If a price list is found in App4Sales matching unicontaCustomer._PriceList, its ID is used. Otherwise, defaults to 0.

Data Mapping - App4Sales Address (from Uniconta DebtorClient)

Each Uniconta customer is mapped to two App4Sales addresses: a 'Visit' address and a 'Delivery' address.

App4Sales Field

Source Field (API/Excel/DB)

Logic/Notes

Visit Address

Visit Address

Visit Address

AddressLine1

unicontaCustomer._Address1

Direct mapping.

AddressLine2

unicontaCustomer._Address2

Direct mapping.

AddressLine3

unicontaCustomer._Address3

Direct mapping.

Country

unicontaCustomer._Country

Determined by GetCountryInfo extension method, which converts Uniconta's CountryCode to ISO2 and then to a display name. If conversion fails, logs an error.

Iso2

unicontaCustomer._Country

Determined by GetCountryInfo extension method, which converts Uniconta's CountryCode to ISO2.

City

unicontaCustomer._City

Direct mapping.

PostCode

unicontaCustomer._ZipCode

Direct mapping.

AddressType

N/A

Hardcoded to 'Visit'.

IsMainAddress

N/A

Hardcoded to 'true' for the visit address.

Delivery Address

Delivery Address

Delivery Address

AddressLine1

unicontaCustomer._DeliveryAddress1

Direct mapping.

AddressLine2

unicontaCustomer._DeliveryAddress2

Direct mapping.

AddressLine3

unicontaCustomer._DeliveryAddress3

Direct mapping.

Country

unicontaCustomer._DeliveryCountry

Determined by GetCountryInfo extension method (with isDeliveryAddress = true), which converts Uniconta's CountryCode to ISO2 and then to a display name. If conversion fails, logs an error.

Iso2

unicontaCustomer._DeliveryCountry

Determined by GetCountryInfo extension method (with isDeliveryAddress = true), which converts Uniconta's CountryCode to ISO2.

City

unicontaCustomer._DeliveryCity

Direct mapping.

PostCode

unicontaCustomer._DeliveryZipCode

Direct mapping.

AddressType

N/A

Hardcoded to 'Delivery'.

IsMainAddress

N/A

Defaulted to 'false' for the delivery address (only visit address is main).

Data Mapping - App4Sales ContactPerson (from Uniconta DebtorClient and ContactClient)

The main contact person is derived directly from the Uniconta DebtorClient, and additional contacts are mapped from associated ContactClient objects.

App4Sales Field

Source Field (API/Excel/DB)

Logic/Notes

Main Contact Person

Main Contact Person

Main Contact Person

FirstName

unicontaCustomer._ContactPerson

Parsed from the full contact person name using GetFirstNameV2().

LastName

unicontaCustomer._ContactPerson

Parsed from the full contact person name using GetLastNameV2().

Phonenumber

unicontaCustomer._MobilPhone / unicontaCustomer._Phone

If 'UseCustomerMobilePhoneAsMainContactPersonPhone' setting is true, uses _MobilPhone; otherwise, uses _Phone.

MobileNumber

unicontaCustomer._MobilPhone

Direct mapping.

Email

unicontaCustomer._ContactEmail

Direct mapping.

Initials

unicontaCustomer._ContactPerson

Parsed from the full contact person name using GetInitialsV2().

FullName

unicontaCustomer._ContactPerson

Direct mapping.

IsMainContactPerson

N/A

Hardcoded to 'true'.

Additional Contact Persons (from unicontaCustomer.Contacts)

Additional Contact Persons (from unicontaCustomer.Contacts)

Additional Contact Persons (from unicontaCustomer.Contacts)

FirstName

contact.Name

Parsed from the full contact name using GetFirstNameV2().

MiddleName

contact.Name

Parsed from the full contact name using GetMiddleName().

LastName

contact.Name

Parsed from the full contact name using GetLastNameV2().

MobileNumber

contact.Mobile

Direct mapping.

Email

contact.Email

Direct mapping.

Initials

contact.Name

Parsed from the full contact name using GetInitialsV2().

FullName

contact.Name

Direct mapping.

IsMainContactPerson

N/A

Hardcoded to 'false'.

Data Mapping - Uniconta Debtor (from App4Sales Customer)

When sending customer data from App4Sales to Uniconta, the App4Sales Customer object is converted to a Uniconta Debtor object.

Uniconta Field

Source Field (App4Sales Customer)

Logic/Notes

_ContactEmail

customer.MainContactPerson?.Email

Email from the main contact person.

_InvoiceEmail

customer.EmailAddressForStock / customer.Email

If customer.EmailAddressForStock is not empty, use it. Otherwise, use customer.Email.

_Name

customer.CustomerName

Direct mapping.

_ContactPerson

customer.MainContactPerson?.FullName

Full name of the main contact person.

_Language

customer.LanguageCode

Parsed from App4Sales LanguageCode (case-insensitive).

_MobilPhone

customer.MainContactPerson?.MobileNumber

Mobile number from the main contact person.

_Phone

customer.Phone

Direct mapping.

_LegalIdent

customer.VatCode

Direct mapping.

_Www

customer.Website

Direct mapping.

_PriceList

customerPriceList?.Code

The code of the selected price list.

_Currency

customerPriceList?.ExternalCurrency

Parsed from the external currency of the selected price list. Defaults to 'XXX' if parsing fails.

_Payment

customer.PaymentConditionCode

Direct mapping.

_Address1 (Visit)

visitAddress.AddressLine1

From the App4Sales 'Visit' address.

_Address2 (Visit)

visitAddress.AddressLine2

From the App4Sales 'Visit' address.

_Address3 (Visit)

visitAddress.AddressLine3

From the App4Sales 'Visit' address.

_Country (Visit)

visitAddress.IsoCode

Converted from App4Sales ISO code to Uniconta CountryCode using CultureHelper.GetCountryFromIso2.

_City (Visit)

visitAddress.City

From the App4Sales 'Visit' address.

_ZipCode (Visit)

visitAddress.PostCode

From the App4Sales 'Visit' address.

_DeliveryAddress1

deliveryAddress.AddressLine1

From the App4Sales 'Delivery' address.

_DeliveryAddress2

deliveryAddress.AddressLine2

From the App4Sales 'Delivery' address.

_DeliveryAddress3

deliveryAddress.AddressLine3

From the App4Sales 'Delivery' address.

_DeliveryCity

deliveryAddress.City

From the App4Sales 'Delivery' address.

_DeliveryCountry

deliveryAddress.IsoCode

Converted from App4Sales ISO code to Uniconta CountryCode using CultureHelper.GetCountryFromIso2.

_DeliveryZipCode

deliveryAddress.PostCode

From the App4Sales 'Delivery' address.

_PaymentMethod

customer.PaymentConditionCode

Parsed as a byte to Uniconta PaymentTypes enum. Only if PaymentConditionCode is not empty.

_Account

customer.CustomerCode / "A4S " + connectorSettings.NextCustomerNumber.ToString()

If customer.CustomerCode is provided, it is used. Otherwise, a new customer code is generated using the "A4S " prefix and the 'NextCustomerNumber' setting.

Data Mapping - Uniconta Debtor User Fields (from App4Sales Customer FreeFields and properties)

Custom free fields from App4Sales can be mapped to Uniconta user-defined fields based on the CustomerFreeFieldsConfiguration setting.

Uniconta User Field (PropertyName)

Source Field (App4Sales Customer)

Logic/Notes

Configured PropertyName

customer.GetPropertyValue(customField.XmlName) / customer.UnknownElements[customField.XmlName]

The mapping is defined in the CustomerFreeFieldsConfiguration setting, which is a JSON string. For each custom field mapping:

  • ObjectName must be "customer".

  • If IsEntityField is true, the value is taken from the App4Sales customer property specified by XmlName.

  • Otherwise, the value is taken from customer.UnknownElements using XmlName as the key.

  • The value is then set to the Uniconta user field based on the PropertyType (Boolean, DateTime, Double, Single, String).

Special Logic & Filters

  • Country Information Handling: The connector attempts to convert Uniconta country codes (CountryCode enum) to ISO2 country codes and then to display names. If this conversion fails for a customer's country, a warning is logged, and the customer's country and ISO2 fields in App4Sales will be null.

  • Price List Association: When retrieving customers from Uniconta, if a customer's _PriceList field does not match any existing App4Sales price list code, a warning is logged, and the UsesPriceField in App4Sales defaults to 0.

  • Customer Free Field Configuration: The mapping of App4Sales free fields to Uniconta user-defined fields is controlled by the CustomerFreeFieldsConfiguration setting, which expects a JSON array of UnicontaCustomFieldMapping objects. This allows flexible mapping of custom data.

  • Customer Creation/Update Logic: When sending customer data to Uniconta:

    • If the App4Sales customer has a CustomerCode, the existing Uniconta customer with that code is updated.

    • If no CustomerCode is present, a new customer is inserted into Uniconta. The new customer's code is generated using the prefix "A4S " followed by the value of the NextCustomerNumber setting. This setting is incremented after each new customer creation.

  • Payment Conditions: The connector updates payment conditions from Uniconta into App4Sales. Existing payment conditions in App4Sales that are no longer present in Uniconta are deleted, and new or updated ones are inserted/updated.

  • Customer Notes: Customer notes are retrieved from Uniconta (UserNotesClient with TableId matching Customers) and updated in the App4Sales database.

Domain Specifics

Customer Core Fields

The core customer record includes essential identity information such as CustomerCode and CustomerName. Commercial settings like Discount (line or end discount based on configuration), VatLiable status, and PaymentConditionCode are synchronized. The UsesPriceField in App4Sales is linked to Uniconta's price lists, allowing customers to have specific pricing. Customer language and assigned employee (customer manager) are also mapped.

Addresses

Each Uniconta customer typically results in two App4Sales addresses: a 'Visit' address and a 'Delivery' address.

  • Visit Address: Mapped from the primary address fields in Uniconta (_Address1, _City, _ZipCode, _Country). This address is marked as the main address in App4Sales.

  • Delivery Address: Mapped from the dedicated delivery address fields in Uniconta (_DeliveryAddress1, _DeliveryCity, _DeliveryZipCode, _DeliveryCountry).

  • Country Normalization: Country codes from Uniconta are converted to ISO2 codes and then to display names using a helper method. If this process fails, the country information for the address will be omitted.

Contacts

Contact persons are synchronized to App4Sales, with one designated as the main contact person.

  • Main Contact Person: Created from the _ContactPerson and _ContactEmail fields of the Uniconta customer. The phone number for the main contact person can be configured to use either the customer's mobile phone or general phone number from Uniconta.

  • Additional Contacts: Any additional contacts associated with the Uniconta customer (unicontaCustomer.Contacts) are also synchronized as contact persons in App4Sales, but are not marked as the main contact.

  • Name Parsing: First name, last name, and initials are parsed from the full contact name strings.

Extra Data & Free Fields

The connector supports flexible mapping of custom data from Uniconta's user-defined fields to App4Sales.

  • CustomerFreeFieldsConfiguration: This setting, provided as a JSON string, defines how Uniconta user fields are mapped. It allows mapping to existing App4Sales customer properties or to a generic list of CustomerFreeField objects if no direct property exists.

  • Data Types: The mapping configuration specifies the expected data type (Boolean, DateTime, Double, Single, String) for correct value retrieval and assignment.

Discounts & Dashboards

While the current analysis of the provided code snippets (CustomersExtensions.cs, CustomersRepository.cs, UnicontaConnector.cs) does not explicitly show direct handling or mapping for "dashboards" or "item class value discounts" in the context of customer updates *from* Uniconta *to* App4Sales, the `InsertOrUpdateCustomerCommand` and `CreateCustomer` methods suggest that when App4Sales sends customer data to Uniconta, `CustomExtraFieldsContext.Instance.All(DbCustomExtraField.EntityCustomer)` are retrieved. This implies custom fields could potentially contain dashboard layouts or discount information. Further investigation would be required to confirm how these specific elements are handled if they are not part of the standard `DebtorClient` or `Customer` models. Customer notes are handled through `GetCustomerNotes` and updated in App4Sales.

Related Settings & Prerequisites

  • Uniconta Username: User credential for Uniconta API.

  • Uniconta Password: Password credential for Uniconta API.

  • Uniconta API Key: API key for Uniconta API.

  • Company ID: Specifies the Uniconta company to connect to.

  • UseLineDiscountPctInsteadOfEndDiscountPct: (Boolean) If true, the line discount percentage from Uniconta is used for the App4Sales Discount field; otherwise, the end discount percentage is used.

  • UseCustomerMobilePhoneAsMainContactPersonPhone: (Boolean) If true, the customer's mobile phone number is used for the main contact person's phone number; otherwise, the general phone number is used.

  • CustomerFreeFieldsConfiguration: (JSON String) A JSON array of UnicontaCustomFieldMapping objects that defines how Uniconta user-defined fields are mapped to App4Sales customer properties or free fields. Example structure: [{ "ObjectName": "Customer", "PropertyName": "AddressLine3", "XmlName": "CustomerAddressLine3", "NameInApp": "Addressline 3", "PropertyType" : "string", "IsEntityField" : "false" }]

  • NextCustomerNumber: (Integer) Used when creating new customers in Uniconta from App4Sales. Provides a sequential number for generating new customer codes with the "A4S " prefix.

  • UseCustomFieldForChamberOfCommerceCode: (String) Specifies the name of a Uniconta custom field that holds the Chamber of Commerce code.

Known Limitations

  • Country information lookup can fail for certain Uniconta country codes, leading to missing country data in App4Sales.

  • Customers from Uniconta without a matching price list in App4Sales will have their UsesPriceField defaulted to 0, which might not accurately reflect their pricing in App4Sales.

  • The current analysis of the provided code snippets does not explicitly show direct handling or mapping for "customer dashboards" or "customer-specific item class discounts" when customers are retrieved from Uniconta into App4Sales. It is assumed these would be handled via generic extra fields if configured.

Did this answer your question?