Extensibility of data synchronization with POS – Option 2

Data export into POS

You may synchronize data unrelated to objects created in POS and synchronized to the ERP system. To do so, use the Synchronization.ExportCustoms procedure. Note that you need to maintain the <Customs><Custom> procedure body structure; however, the structure under the <Custom> node is completely arbitrary.

It is recommended that the structure of the tables from which you select data to be sent have the form of a tree, and the main table have the following columns:

  • GUID – it will ensure object identification between POS and ERP
  • Id – for structure relations
  • Type – if you would like to differentiate data in the DS, especially if there are separate extensions
  • WasSentToERP – to filter data that has already been transferred

Marking transferred data

You can use the standard method for marking transferred objects to mark non-standard objects.

To do so, overload the ISynchronizationRepository service method (this area has no extension points).

public class SynchronizationRepositoryExt : SynchronizationRepository
{
   public override void MarkIfWasSentToERP(string xml)
   {
      base.MarkIfWasSentToERP(xml);

      using (var context = new POSDBContext())
      {
         context.ExecuteProcedure("Synchronization.MarkSentCustomData", xml);
      }
   }
}

Inside, you can, for instance, call the procedure that will mark the transferred objects.

CREATE PROCEDURE [Synchronization].[MarkSentCustomData]
    @p0 xml
AS
BEGIN
    UPDATE CustomSchema.CustomRootTable
    SET WasSentToERP = 1
    Where GUID in (SELECT xmlData.Col.value('@GUID','varchar(max)') FROM @p0.nodes('/Customs/Custom') xmlData(Col))
END
GO

Example of export

CREATE PROCEDURE [Synchronization].[ExportCustoms] 
AS
BEGIN
    SET NOCOUNT ON;

    select
        pad.GUID 			as [@GUID],
        pad.Type as [@Type],
        pad.Data1 		as [@Data1],
        Synchronization.GetDatetimeString(pad.ChangeDate) 							as [@ChangeDate],
        (
            select			
td.Number 			as [@NumberString], 
td.Status	 			as [@Status], 
td.Value 				as [@Value]
            from 				CustomSchema.Table1 td 			where pad.Id = td.RootId
            for xml path('Table1'), root('Tables1'), type
        ),		
        (
            select				
ti.ToPayNet 				as [@ToPayNet], 
                ti.Points				 as [@Points], 
ti.ToPay				as [@ToPay]
            from 			CustomSchema.Table2 ti 			where 								pad.Id = ti.RootId
            for xml path('Table2'), root('Tables2'), type
        )

    from CustomSchema.RootData pad
    where pad.WasSentToERP = 0

    for xml path('Custom'), root('Customs')
    
END
GO

 

Import on the DataService side

Data import is performed using the IDataCustomService service and overloading the SaveCustom method. As an argument, the method gets each Custom row as an XElement object.

To handle multiple extensions, it is necessary to use extension points for DataService.

Snippet for import

[DataServiceBusinessModule]
public static class Module    
{
   [MethodInitializer]
   public static void Initialize()        
   {
       var dataCustomService = IoC.Container.Resolve<IDataCustomExtensionPointService>();
       dataCustomService.OnSaveCustomEvent += DataCustomService_OnSaveCustomEvent;
   }
   private static void DataCustomService_OnSaveCustomEvent (object sender, XEEventArgs e)
   {
   //deserialization + saving data
   }
}

Czy ten artykuł był pomocny?