Spis treści
Dodawanie i aktualizacja danych
Czynność po stronie Altum
W bazie Altum istnieje procedura POS.ExportCustomObjects. Należy ją nadpisać, tak by pobierała z bazy dane, które mają trafić do danego POS-a, i zwracała je w formacie XML.
Do procedury są przekazywane parametry pozwalające ograniczyć i dostosować zestaw danych wysyłanych do konkretnego POS-a:
- @rowVersion (bigint) – Wartość pozwalająca przeprowadzać synchronizację różnicową. Jest to wartość znajdująca się w XML wygenerowanym przez tę procedurę podczas ostatniej pomyślnej synchronizacji (w atrybucie RowVersion).
- @companyUnitId (int) – Id centrum, w którym zdefiniowano POS-a (CompanyStructure.CompanyUnits)
- @pointOfSaleId (int) – Id POS-a (Synchronization.PointsOfSales)
- @languageId (int) – Id języka danych (Dictionaries.Languages)
Przy eksporcie danych z kolumn typu bit i datetime należy korzystać z funkcji POS.GetBitString i POS.GetDatetimeString.
Czynność po stronie POS
W bazie POS-a istnieje procedura Synchronization.ImportCustomObjects. Należy ją nadpisać, tak by aktualizowała w bazie POS-a tabele na podstawie otrzymanych od Altum danych w formacie XML – tych wygenerowanych przez procedurę POS.ExportCustomObjects.
Przykład
Przykład pokazuje synchronizację różnicową danych z dwóch tabel – eksport z bazy Altum i import do bazy POS-a:
- SecDictionaries.Dic_PaymentForms -> Configuration.CustomPaymentForms
- dbo.Dic_Country -> Configuration
a) Procedura eksportująca
ALTER PROCEDURE [POS].[ExportCustomObjects] @rowVersion bigint, @companyUnitId int, @pointOfSaleId int, @languageId int AS BEG+IN SET NOCOUNT ON; declare @dbts bigint = cast(@@DBTS as bigint) select @dbts as [@RowVersion], (select pf.Id as [@Id], pf.Name as [@Name], pf.CategoryId as [@Type], POS.GetBitString(pf.Active) as [@IsActive] from SecDictionaries.Dic_PaymentForms pf where pf.Timestamp > @rowVersion for xml path('PaymentForm'), type), (select c.Id as [@Id], c.Code as [@Code], c.Name as [@Name], POS.GetBitString(c.Active) as [@IsActive] from dbo.Dic_Country c where c.Timestamp > @rowVersion for xml path('Country'), type) for xml path('CustomObjects') END
b) Procedura importująca
ALTER PROCEDURE [Synchronization].[ImportCustomObjects] @XML xml AS BEGIN SET NOCOUNT ON; -- Countries -- select doc.col.value('@Id', 'int') Id, doc.col.value('@Code', 'nvarchar(50)') Code, doc.col.value('@Name', 'nvarchar(100)') Name, doc.col.value('@IsActive', 'bit') IsActive into #Countries from @XML.nodes('/DataFromERP/CustomObjects/Country') doc(col) update pos set Code = erp.Code, Name = erp.Name, IsActive = erp.IsActive from Configuration.CustomCountries pos join #Countries erp on erp.Id = pos.Id insert into Configuration.CustomCountries ( Id, Code, Name, IsActive ) select Id, Code, Name, IsActive from #Countries erp where not exists (select 1 from Configuration.CustomCountries where Id = erp.Id) -- Payment forms -- select doc.col.value('@Id', 'int') Id, doc.col.value('@Name', 'nvarchar(50)') Name, doc.col.value('@Type', 'tinyint') [Type], doc.col.value('@IsActive', 'bit') IsActive into #PaymentForms from @XML.nodes('/DataFromERP/CustomObjects/PaymentForm') doc(col) update pos set Name = erp.Name, Type = erp.Type, IsActive = erp.IsActive from Configuration.CustomPaymentForms pos join #PaymentForms erp on erp.Id = pos.Id insert into Configuration.CustomPaymentForms ( Id, Name, Type, IsActive ) select Id, Name, Type, IsActive from #PaymentForms erp where not exists (select 1 from Configuration.CustomPaymentForms where Id = erp.Id) END
Obsługa słowników uniwersalnych
Aktualizacja procedury eksportującej
W procedurze POS.ExportGenericDirectories, w klauzuli WHERE należy uwzględnić InternalName słownika, który tez ma być synchronizowany.
W procedurze POS.ExportGenericDirectoryValues, w klauzuli WHERE należy uwzględnić InternalName słownika, który też ma być synchronizowany.
Klucze obce do schematu Altum
Dla tabel synchronizowanych
Dostępność obiektów, uprawnienia itp. mogą, na poziomie wiersza w danej tabeli, wpływać na to, które dane są synchronizowane. Przykładem mogą być Kontrahenci, grupy kontrahentów, magazyny, rejestry, formy płatności itd.
Aby uniknąć wielokrotnej ewaluacji, które dane należy synchronizować w tabelach pochodnych (na podstawie FK) należy posiłkować się tabelą POS.SentObjects.
Przykład: Eksport definicji podatków powiązanych z kontrahentem
(select ven.Id as [@Id], ven.ActivityId as [@ActivityId], ven.VendorId as [@VendorId] from Implementations.VendorActivityConnectionsEcoTax ven inner join Implementations.ActivityEcoTax ac on ven.ActivityId = ac.Id inner join Implementations.SettingsEcoTax sett on ac.Id = sett.CompanyActivityId and sett.CompanyId = @companyUnitId inner join POS.SentObjects so on so.ObjectId = ven.VendorId and so.SyncTypeId = 14 and so.POSId = @pointOfSaleId where ven.Timestamp > @rowVersion for xml path('VendorActivityConnectionsEcoTax'), type)
wartość typu synchronizowanego obiektu można znaleźć w tabeli POS.SyncTypes.
Dla tabel niesynchronizowanych
Należy samodzielnie zaimplementować proces synchronizacji, tak jakby tabela pochodziła z doróbki.
Usuwanie danych
Czynności po stronie Altum
a) Do tabeli DeletionTypes dodać wpis z Id >= 1000 oraz unikatową nazwą typu usuwanych obiektów.
b) W triggerze AFTER DELETE tabeli, z której usuwanie danych ma być synchronizowane do POS, dodawać do tabeli POS.DeletedObjects wpisy o usuniętych obiektach. Kolumny do wypełnienia:
- DeletionTypeId – identyfikator typu zdefiniowanego w pkcie a)
- Ident – identyfikator usuniętego obiektu. Może to być liczba (int), GUID (uniqueidentifier), nvarchar lub zbiór wartości rozdzielonych znakiem „|”, np. „3428|654”. Patrz też punkt dot. czynności po stronie POS (kolumny IdentColumnName, IdentColumnType).
- POSId – identyfikator POS-a (Synchronization.PointsOfSales) – należy go wypełnić, jeśli obiekt powinien zostać usunięty tylko z konkretnego stanowiska POS, albo pozostawić NULL, jeśli powinien zostać usunięty na wszystkich stanowiskach.
Czynności po stronie POS
Do tabeli Synchronization.DeletionTypes dodać wiersz definiujący sposób obsługi przez mechanizm synchronizacji informacji o usunięciu obiektów przychodzący z ERP-a.
Dostępne są dwa tryby usuwania: automatyczny i niestandardowy.
- W trybie automatycznym mechanizm synchronizacji będzie automatycznie usuwał dane z podanej tabeli, identyfikując wiersze na podstawie podanych nazw kolumn (muszą być uzupełnione wartości w kolumnach TableName, IdentColumnName, IdentColumnType, a także NULL w kolumnie CustomProcName). Stosowany do usuwania na POS-ie niemal wszystkich typów obiektów usuwalnych w ERP-ie (patrz standardowe wpisy w tabeli Synchronization.DeletionTypes).
- Tryb niestandardowy natomiast wymaga podania procedury obsługującej usuwanie obiektów danego typu (musi być wypełniona kolumna CustomProcName). Używany jest, gdy warunek usunięcia jest bardziej skomplikowany i nie da się zastosować mechanizmu automatycznego lub gdy przy usuwaniu należy wykonać dodatkowe operacje.
Tabela Synchronization.DeletionTypes zawiera następujące kolumny:
- DelType – nazwa taka, jak w bazie Altum w tabeli DeletionTypes.
- Order – liczba wyznaczająca kolejność usuwania typów obiektów.
- TableName [tylko tryb automatyczny] – nazwa tabeli, z której obiekty mają być automatycznie usuwane w ramach danego typu DelType.
- IdentColumnName [tylko tryb automatyczny] – nazwy kolumn (rozdzielonych znakiem „|”), wg których ma się odbywać automatyczna identyfikacja usuwanych wierszy, np. „Id”, „GUID”, „PriceTypeId|CustomerGroupId”. Ich liczba i kolejność musi się zgadzać z wartością wpisywaną w bazie Altum do kolumny POS.DeletedObjects.Ident.
- IdentColumnType [tylko tryb automatyczny] – typy kolumn zdefiniowanych jako IdentColumnName, w tej samej liczbie i kolejności, np. „int”, „uniqueidentifier”, „int|int”. W przypadku typu nvarchar(x) wpisujemy „nvarchar”.
- CustomProcName [tylko tryb niestandardowy] – nazwa procedury odpowiadającej za usunięcie obiektów danego typu. Powinna korzystać z danych z tabeli tymczasowej #DeletedObjects. Patrz istniejące procedury Synchronization.DeleteCustomerPriceTypes, Synchronization.DeleteWarehouseDocuments.