eAccounting Connector - CustomerUpdate
This function synchronizes customer-related data from the eAccounting ERP system into the App4Sales platform. It processes customer core information, associated addresses, contact persons, item class discounts, and customer-specific dashboards. The update runs in batches and incorporates various transformations, validations, and conditional logic to ensure data integrity and consistency.
3. Data Source Configuration
The CustomerUpdate function primarily receives customer data as a list of Customer objects from the eAccounting connector. Additionally, supplementary customer data can be sourced from CSV files, accessible via the _databaseManager.ExtraCustomerData. This extra data is provided as a dictionary where the key is the CustomerCode and the value is a CsvCustomer object.
Customer Core Fields
App4Sales Field | Source Field (API/Excel/DB) | Logic/Notes |
|
| Mandatory. Customers with an empty |
|
| Mandatory. Customers with an empty |
| Derived |
|
|
| If |
|
| Truncated to seconds precision. |
|
| Set to |
|
| Mapped via |
|
|
|
|
|
|
|
| Set to |
|
| Whitespace is trimmed from the email address. |
|
| If the source contains XML other than an empty |
|
| Set to |
|
| Set to |
|
| If |
|
| If |
|
| If |
Addresses
App4Sales Field | Source Field (API/Excel/DB) | Logic/Notes |
|
|
|
|
| Inherited from the parent customer. |
|
| If empty, a default ID is generated via |
|
| Used to identify existing addresses. Reset to |
|
|
|
|
|
|
|
| If empty, defaults to |
|
| If |
|
| If |
|
| If |
|
|
|
|
|
|
Contacts
App4Sales Field | Source Field (API/Excel/DB) | Logic/Notes |
|
| Inherited from the parent customer. |
|
| If |
|
| If |
|
| If |
|
| If null, constructed from |
| Derived | First character of |
|
| Set to |
|
| If empty and |
|
|
|
|
| If not empty, deserialized into |
Extra Data & Free Fields
This section details how additional data, potentially from CSV sources, can extend or override standard customer fields and how generic "free fields" and item filters are processed.
App4Sales Field | Source Field (API/Excel/DB) | Logic/Notes |
(Various Customer Fields) |
| Properties of the |
|
| Key-value pairs from |
|
| If |
|
| Only processed if the connector setting |
|
| If the source |
|
| Similar to customer dynamic free fields, if the source |
Discounts & Dashboards
This section outlines how customer-specific dashboards are processed and stored, and how discounts based on item class values are handled.
Item Class Value Discounts
App4Sales Field | Source Field (API/Excel/DB) | Logic/Notes |
|
| Inherited from the parent customer. |
|
| Only discounts with a value greater than 0 and not null are processed and stored. |
(Other |
| The |
Customer Dashboards
App4Sales Field | Source Field (API/Excel/DB) | Logic/Notes |
|
| The |
|
| Used to associate the dashboard with the customer. |
Customer Notes
App4Sales Field | Source Field (API/Excel/DB) | Logic/Notes |
|
| If |
Special Logic & Filters
Invalid Customer Filtering: Customers with empty
CustomerNameorCustomerCodeare filtered out at the beginning of theUpdatemethod and logged with a warning.Batch Processing: Customer updates are processed in batches of 100 customers (
batchSize = 100) to manage memory and database transactions efficiently.Customer Reactivation Logic: If
UpdaterHelper.IsUpdateris true, the system attempts to reactivate previously inactive customers. It looks forCustomerGuidsassociated with customer codes prefixed with "~" (_customerCodeGuidReactivationLinks) and reuses them to preserve historical data (e.g., notes, order links).Price Deduplication Migration: If
EnablePriceDeduplicationsetting is enabled (either inConnectorBaseSettingsorSyncSettings), existing price list IDs (UsesPriceFieldandActionPriceList) are potentially migrated to new IDs based on a lookup table stored inKeySettings.GenericPriceListMigrations. If a migrated price list ID is not found in existing price lists,ActionPriceListis nulled, andUsesPriceFielddefaults to 1.Error Handling: A
try-catchblock surrounds the processing of each customer within a batch. Errors are logged, and_portalServerProvider.ResetDataUpdateIntervals("CustomerUpdate")is called, likely to prevent repeated failed updates.Address Validation: In
ProcessAddresses, addresses are filtered to ensure they are not empty or have anExternalIdset. Logic exists to ensure at least "Visit" and "Delivery" address types are present, even if dummy addresses need to be created.Item Class Map Loading:
itemClassMapis only built (ItemClassesContext.Instance.BuildItemClassMap()) ifextraCustomerDatais available andAdministrationSession.CurrentSession.SyncSettings.CustomerItemFilteris enabled.USA VAT Handling: For administrations in the USA (
AdministrationSession.CurrentSession.Administration.IsUSA),VatCodeis set tonullandVatLiabletofalseto prevent storing VAT information not relevant to USA tax regulations.Post-Script Customer Validation: After
_scriptingService.ExecuteScriptwith "UpdateCustomers" (for the batch), addresses and contacts are re-validated to ensure they belong to customers that were not removed by the script.
Script Hooks
The CustomerUpdate function utilizes several scripting hooks, allowing for custom logic execution at different stages of the update process:
BeforeUpdateCustomers: Executed before any customer processing begins for a batch. It receives the list of customers and can be used to modify or filter them prior to the main update logic.UpdateCustomers(Batch Specific): Executed after each customer in a batch has been processed internally but before the batch is committed to the database. This hook allows for custom transformations or validations on the processed customer objects before they are saved.UpdateCustomers(Final): Executed once at the very end of theUpdatemethod, after all batches have been processed, committed, and contact persons have been updated. This can be used for final post-processing or triggering external notifications.
Related Settings & Prerequisites
Customer Item Filter (
SyncSettings.CustomerItemFilter):Purpose: Controls whether item filters specified in extra customer data (e.g., from CSV
ItemFilter_fields) are processed and applied to customers.Impact: If enabled,
ItemFilter_values fromCsvCustomer.UnknownElementswill be used to populatecustomer.ItemFilter. When updating a single customer, if this setting is enabled, the existingItemFilterfrom the database is read to prevent losing fixed item filters during updates from other sources (e.g., mobile apps).
Default Action Price List Code (
ConnectorBaseSettings.DefaultActionPriceListCode):Purpose: Specifies a default action price list code to be applied to customers if they don't have one explicitly set.
Impact: If this setting has a value and
customer.ActionPriceListis not set, the system attempts to find a price list ID using this code and assigns it tocustomer.ActionPriceList.
Enable Price Deduplication (
ConnectorBaseSettings.EnablePriceDeduplication/SyncSettings.EnablePriceDeduplication):Purpose: Enables a mechanism to deduplicate price lists, which might involve migrating existing price list IDs to new ones.
Impact: If enabled, the system checks for price list migration rules defined in
KeySettings.GenericPriceListMigrations. It will then attempt to updatecustomer.UsesPriceFieldandcustomer.ActionPriceListto their migrated IDs. If a migrated price list ID is not found in the existing price lists,ActionPriceListis nulled, andUsesPriceFieldis defaulted to 1.
Administration Country (
Administration.IsUSA):Purpose: Indicates whether the current administration is configured for the USA.
Impact: If true,
customer.VatCodeis set tonullandcustomer.VatLiableis set tofalse. Also influences address formatting.
Known Limitations
Mandatory Customer Fields: The update process strictly requires
CustomerCodeandCustomerNameto be non-empty. Customers lacking these fields are skipped entirely.CustomerDashboard Format: The
customer.CustomerDashboardfield is expected to be a Base64 encoded string. Any other format will lead to the dashboard data being discarded.Specific CSV Extra Data Structure: The
ProcessExtraDataForCustomermethod assumes a specific naming convention for free fields (FreeField_) and item filters (ItemFilter_) within theCsvCustomer.UnknownElementsdictionary. Deviations will lead to these fields not being processed correctly.Price Deduplication Dependency: The price deduplication feature relies on a
KeySettings.GenericPriceListMigrationsentry. If this setting is not properly configured, price list IDs might not be correctly migrated, potentially leading to incorrect pricing.Address Deduplication/Uniqueness: While there's logic to create missing Visit/Delivery addresses, the overall address processing does not explicitly prevent the creation of logically duplicate addresses if the incoming data contains them with different
AddressIdorExternalIdvalues, beyond theDistinctByon(e.CustomerGuid, e.AddressId, e.AddressType). It mainly focuses on ensuring certain types exist.Contact Person ID Generation in Updater Mode: In Updater mode, if a contact person lacks a
ContactId, a hash code-based ID is generated. This might not be a stable or human-readable identifier.Customer Note Handling: Customer notes are deleted and re-inserted as a single "Backoffice note". This overwrites any previous "Backoffice note" and does not support multiple notes for this specific type of note.