Skip to main content

Logic4 - Customer sync

Logic4 Connector - Customer Update This document describes the customer update process for the Logic4 connector. This process synchronize...

Updated over a week ago

Logic4 Connector - Customer Update

This document describes the customer update process for the Logic4 connector. This process synchronizes customer data, including core customer information, addresses, and contact persons, from the Logic4 ERP system into the App4Sales internal data structure. It also handles related entities such as payment conditions and sales representatives. This update typically runs on a scheduled basis to ensure customer information is always up-to-date in App4Sales.

Data Source Configuration

The Logic4 connector retrieves customer-related data through API calls to the Logic4 system. Authentication for these API calls is handled internally using an AccessToken. The specific endpoints used for customer data retrieval are:

  • Customers: Constants.Routes.Customer

  • Customer Contacts: Constants.Routes.CustomerContact

  • Customer Addresses: Constants.Routes.CustomerAddress

  • Payment Methods: Retrieved via CustomersRepository.GetCustomersPaymentMethods()

Data is pulled from the Logic4 API.

Data Mapping Tables

Customer Core Fields

App4Sales Field

Source Field (API/Excel/DB)

Logic/Notes

CustomerCode

customer.Id

Converted to string.

CustomerName

customer.CompanyName

Direct mapping.

ChamberOfCommerceCode

customer.ChamberOfCommerceCode

Direct mapping.

Discount

customer.Discount

Direct mapping.

VatLiable

customer.VatCode?.Id == settings.VatLiableId

Boolean indicating if the customer is VAT liable. Compares the Id of the Logic4 customer's VatCode with the VatLiableId setting from the connector configuration.

Website

customer.Website

Direct mapping.

Phone

customer.TelephoneNumber

Direct mapping.

Email

customer.EmailAddress

Direct mapping.

VatCode

customer.VatNumber

Direct mapping.

Fax

customer.FaxNumber

Direct mapping.

PaymentConditionCode

paymentMethods.FirstOrDefault(pm => pm.Id == customer.PaymentMethodId)?.Description

Looks up the payment method description from the list of paymentMethods (retrieved by UpdatePaymentConditions()) based on customer.PaymentMethodId.

Addresses

App4Sales Field

Source Field (API/Excel/DB)

Logic/Notes

Country

address.IsoCode (from Logic4CustomerAddress) or entity.IsoCode (from Logic4Customer)

Derived from Logic4 ISO code (ISO3) by converting to ISO2 and then looking up the country name.

City

address.City or entity.City

Direct mapping.

PostCode

address.Zipcode or entity.ZipCode

Direct mapping.

AddressId

address.Id

Converted to string. Only for addresses explicitly from Logic4CustomerAddress.

ExternalId

address.Id

Converted to string. Only for addresses explicitly from Logic4CustomerAddress.

AddressLine

address.Street, address.HouseNumber, address.HouseNumberAddition

Combined into a single address line object.

AddressLine2

address.Address2

Direct mapping. Only for addresses explicitly from Logic4CustomerAddress.

State

address.Province?.Name

Direct mapping. Only for addresses explicitly from Logic4CustomerAddress.

IsoCode

address.IsoCode or entity.IsoCode

Derived from Logic4 ISO code (ISO3) by converting to ISO2.

Email

address.Email or entity.EmailAddress

Direct mapping.

Phone

address.TelephoneNumber or entity.TelephoneNumber

Direct mapping.

AddressType

address.Type?.Id (from Logic4CustomerAddress) or constant

Mapped from Logic4 address types: Delivery (for Logic4 Delivery, FixedDelivery, or type 0 from contact persons), Invoice (for Logic4 Invoice, FixedInvoice). Default customer addresses are always Visit type.

IsMainAddress

address.IsMainContact or constant

Set to true for default customer addresses; directly mapped for other addresses.

Contact Persons

App4Sales Field

Source Field (API/Excel/DB)

Logic/Notes

FirstName

customerContact.FirstName

Direct mapping.

LastName

customerContact.LastName

Direct mapping.

MiddleName

customerContact.InsertionName

Direct mapping.

FullName

customerContact.FirstName, customerContact.InsertionName, customerContact.LastName

Concatenated string.

MobileNumber

customerContact.MobileNumber

Direct mapping.

Email

customerContact.EmailAddress

Direct mapping.

Phonenumber

customerContact.TelephoneNumber

Direct mapping.

IsMainContactPerson

customerContact.IsMainContact

Direct mapping.

Gender

customerContact.Gender?.Name

Direct mapping of the name of the gender.

Initials

customerContact.Initials

Direct mapping.

ContactId

customerContact.Id

Converted to string.

Special Logic & Filters

  • Invalid Customer Filtering: Customers with an empty CustomerName or CustomerCode are filtered out and a warning is logged.

  • Batch Processing: Customer data is processed and updated in batches of 100 to optimize database performance.

  • Inactive Customer Reactivation: During updates, if an inactive customer with a matching CustomerCode exists, its CustomerGuid is reused to maintain historical data and links (e.g., existing customer notes and order links).

  • CustomerGuid Generation: If no existing CustomerGuid is found or reused, a new GUID is generated for the customer.

  • Timestamp Truncation: Created and Sysmodified timestamps are truncated to the nearest second before saving to prevent potential SQL execution timeouts due to millisecond precision differences.

  • Password Handling (Updater Mode): When the connector is running in updater mode, the PasswordWebshop field for both the customer and their contact persons is explicitly set to null.

  • Language Code Mapping: If a customer.LanguageCode is provided, it is mapped to a standardized App4Sales language code based on configured mappings.

  • Default Action Price List: If the connector setting DefaultActionPriceListCode is configured and a customer does not have an action price list specified, the default action price list is applied.

  • Payment Condition Sanitization: Empty string values for PaymentConditionCode are converted to null to avoid foreign key constraint issues in the database.

  • Address Normalization:

    • Email addresses within addresses are trimmed, and invalid XML characters are removed.

    • Country codes are mapped and ISO2 codes are normalized.

    • If no valid addresses are present for a customer but an ISO2 code exists, a dummy "Visit" address is created to store the ISO2.

    • The system ensures that at least one "Visit" and one "Delivery" address type exist for each customer. If only one of these types is present, a shallow copy is made and assigned the missing type.

  • Email Trimming: Customer and contact person email addresses are trimmed of leading/trailing whitespace.

  • Contact Person Name Filling: If individual name components (FirstName, MiddleName, LastName) are missing but FullName is present, the FullName is parsed to populate the individual fields. Conversely, if individual fields are present but FullName is missing, FullName is constructed. Initials are also generated.

  • ContactId Generation (Updater Mode): In updater mode, if a contact person's ContactId is empty, a hash code is generated and used as the ContactId.

  • USA VAT Handling: For administrations configured for the USA, VatCode is set to null and VatLiable is set to false, as VAT information is handled differently.

  • Price Deduplication: If enabled, customer UsesPriceField and ActionPriceList are updated to use deduplicated price list IDs if a migration mapping exists. If a mapped price list no longer exists, UsesPriceField defaults to 1 and ActionPriceList is set to null.

Domain Specifics

Customer Core Fields

This section details how the core customer account information is processed and mapped from Logic4 to App4Sales.

Addresses

Addresses are synchronized with special attention to normalization and ensuring the presence of essential address types. Logic4 addresses are processed to create or update corresponding App4Sales address records.

Contacts

Contact persons associated with customers are synchronized. The system handles the identification of main contacts and ensures that contact information is properly formatted.

Extra Data & Free Fields

  • Free Field Configuration (CustomerFreeFieldsConfiguration setting): This setting allows administrators to define custom mappings for additional customer fields from Logic4 that are not part of the standard App4Sales customer model. The setting expects a JSON array of objects, where each object defines:

    • ObjectName: Must be "Customer".

    • PropertyName: The name of the property in the Logic4 customer entity to extract.

    • NameInApp: The display name for this free field in App4Sales.

    Values for these fields are extracted from "unknown elements" within the Logic4 customer data and stored as CustomerFreeField objects in App4Sales' FreeFieldList.

  • Extra Data from CSV/FTP (ProcessExtraDataForCustomer): If additional customer data is provided via CSV or FTP, this data can overwrite standard customer properties in App4Sales based on matching property names. Furthermore:

    • Any fields in the extra data prefixed with "FreeField_" (e.g., "FreeField_CustomData") are treated as additional free fields and added to the customer's FreeFieldList. The prefix is removed for the display caption.

    • If the CustomerItemFilter setting is enabled, fields prefixed with "ItemFilter_" are processed to create item filters for the customer. The values are expected to be separated by '~' and are mapped to existing item classes and their values.

  • Dynamic Free Fields: If customer.DynamicFreeFields contains XML, it is deserialized and converted to App4Sales' ExtraFields using configured custom extra fields. This applies to both customer and contact person dynamic free fields.

  • FreeFieldList Serialization: If a FreeFieldList exists but customer.FreeFields is empty, the FreeFieldList is serialized into an XML string and stored in customer.FreeFields.

Discounts & Dashboards

  • Item Class Value Discounts: Discounts defined per item class value (DiscountsPerItemCLassValue) are synchronized. Only discounts with a value greater than zero are considered. Each discount is associated with the customer's CustomerGuid and updated in the database via the OPTA4SUpdateItemClassValueDiscountsBatch stored procedure.

  • Customer Dashboards: If a CustomerDashboard (Base64 encoded string) is present in the incoming Logic4 customer data, it is decoded and saved as a Dashboard object using _customerDataManager.SaveDashboards. After saving, the CustomerDashboard field on the customer object is cleared.

  • Customer Notes: If a CustomerNote is present, any existing "BackOffice" notes for that customer are deleted from the CustomerNotes table, and a new note with the subject "Backoffice note" is inserted.

Related Settings & Prerequisites

The following connector settings and prerequisites influence the Customer Update process:

  • VatLiableId: (Logic4 Connector Setting) An integer ID used to identify VAT liable customers in Logic4.

  • CustomerFreeFieldsConfiguration: (Logic4 Connector Setting) A JSON string defining how custom customer fields from Logic4 should be mapped and displayed as free fields in App4Sales.

  • EnablePriceDeduplication: (Global Sync Setting) If enabled, price lists are subject to a migration lookup to use deduplicated IDs, affecting UsesPriceField and ActionPriceList.

  • CustomerItemFilter: (Global Sync Setting) If enabled, allows the processing of item filters defined in extra customer data (e.g., from CSV/FTP).

  • DefaultActionPriceListCode: (Global Connector Setting) Specifies a default action price list to be applied to customers who do not have one assigned.

Known Limitations

  • The connector assumes that DeliveryDate is supplied; no default is applied by the connector if missing. (Note: this was mentioned in Context.md as an example, but not found explicitly in code related to customer update).

  • Price lists are not yet fully implemented for Logic4 and are marked with a TODO in the code.

  • The mapping of CountryCode and CountryId for addresses from Logic4 is noted as not easily mappable to a known list in App4Sales, which might lead to incomplete country information in some cases.

Did this answer your question?