Skip to main content
Solved

23R2 - How to Create a New Entity for Shopify Connector to Sync Data to Shopify

  • 22 July 2024
  • 1 reply
  • 60 views

Hi Team,

I am working with 23R2 (Build 23.209.0023) Shopify connector. I have a custom table and a custom screen. I want to create a new Entity similar to the Stock Item and sync the data from custom table to Shopify as stock items. I tried to create a new graph using SPProductProcessor but getting error while inheriting from this class. Then I used ProductProcessorBase, using which I am able to get the data in Sync History but during sync objects are getting null and further processes are failing.

Can anyone suggest the best possible way to achieve it.

Thank you in advance !

1 reply

Userlevel 5
Badge +1

@vivekm , create a new entity and handle the sync process are very complicated, based on your requirement, the following are the key points to create a new entity processor:

  1. Create a new entity bucket object
    public class SPCustomItemEntityBucket : SPProductEntityBucket<MappedStockItem>
    {
    }

     

  2. Create a new Processor that inherits from BCProcessorSingleBase, and attached the BCProcessorAttribute to the new Processor
    [BCProcessor(typeof(SPConnector), "CI", "Custom Item", 39,
    IsInternal = false,
    Direction = SyncDirection.Export,
    PrimaryDirection = SyncDirection.Export,
    PrimarySystem = PrimarySystem.Local,
    PrimaryGraph = typeof(PX.Objects.IN.InventoryItemMaint),
    ExternTypes = new Type[] { typeof(ProductData) },
    LocalTypes = new Type[] { typeof(StockItem) },
    AcumaticaPrimaryType = typeof(PX.Objects.IN.InventoryItem),
    AcumaticaPrimarySelect = typeof(Search<
    PX.Objects.IN.InventoryItem.inventoryCD,
    Where<PX.Objects.IN.InventoryItem.stkItem, Equal<True>>>),
    URL = "products/{0}",
    Requires = new string[] { }
    )]
    public class SPCustomItemProcessor : BCProcessorSingleBase<SPCustomItemProcessor, SPCustomItemEntityBucket, MappedStockItem>
    {
    }

     

  3. Create data provider and Initialize the processor
    [InjectDependency]
    protected ISPRestDataProviderFactory<IProductRestDataProvider<ProductData>> productDataProviderFactory { get; set; }

    [InjectDependency]
    protected ISPRestDataProviderFactory<IChildRestDataProvider<ProductVariantData>> productVariantDataProviderFactory { get; set; }
    protected IProductRestDataProvider<ProductData> productDataProvider;
    protected IChildRestDataProvider<ProductVariantData> productVariantDataProvider;
    #region Constructor
    public override async Task Initialise(IConnector iconnector, ConnectorOperation operation, CancellationToken cancellationToken = default)
    {
    await base.Initialise(iconnector, operation, cancellationToken);
    var client = SPConnector.GetRestClient(GetBindingExt<BCBindingShopify>());

    productDataProvider = productDataProviderFactory.CreateInstance(client);
    productVariantDataProvider = productVariantDataProviderFactory.CreateInstance(client);
    }
    #endregion

     

  4. Override the key methods to fetch data/mapping data/save data 
    public override Task FetchBucketsForImport(DateTime? minDateTime, DateTime? maxDateTime, PXFilterRow[] filters, CancellationToken cancellationToken = default)
    {
    throw new NotImplementedException();
    }

    public override Task<EntityStatus> GetBucketForImport(SPCustomItemEntityBucket bucket, BCSyncStatus status, CancellationToken cancellationToken = default)
    {
    throw new NotImplementedException();
    }

    public override Task SaveBucketImport(SPCustomItemEntityBucket bucket, IMappedEntity existing, string operation, CancellationToken cancellationToken = default)
    {
    throw new NotImplementedException();
    }

    public override async Task FetchBucketsForExport(DateTime? minDateTime, DateTime? maxDateTime, PXFilterRow[] filters, CancellationToken cancellationToken = default)
    {
    //It is used for screen BC501000(Prepare Data):
    //1. Fetch the data from ERP by BQL query or CBAPI
    //2. Created the MappedStockItem instance and call EnsureStatus method to create the sync record.
    //MappedStockItem mapped = new MappedStockItem(entity, entity.SyncID, entity.SyncTime); //entity is a StockItem object.
    //EntityStatus status = EnsureStatus(mapped, SyncDirection.Export);
    }

    public override async Task<EntityStatus> GetBucketForExport(SPCustomItemEntityBucket bucket, BCSyncStatus status, CancellationToken cancellationToken = default)
    {
    //This is the method for fetching ERP data during the export data process.
    //1.Get the item details from ERP
    //2.Assign the local item to the bucket, the bucket.Product.Local is a StockItem; bucket.Product.Exten is a ProductData(a data model that represents the Shopify product)
    //3.Call EnsureStatus to refresh the sync status.
    //MappedStockItem obj = bucket.Product = bucket.Product.Set(entity, entity.SyncID, entity.SyncTime);
    //EntityStatus status = EnsureStatus(obj, SyncDirection.Export);
    }

    public override async Task MapBucketExport(SPCustomItemEntityBucket bucket, IMappedEntity existing, CancellationToken cancellationToken = default)
    {
    //for the default mapping between ERP data and external data object.
    //bucket.Product.Local is a StockItem
    //bucket.Product.Exten is a ProductData(a data model that represents the Shopify product)
    }

    public override async Task SaveBucketExport(SPCustomItemEntityBucket bucket, IMappedEntity existing, string operation, CancellationToken cancellationToken = default)
    {
    //for saving data to External platform during the export process.
    //Use the productDataProvider to create/update ProductData to Shopify
    //Use the productVariantDataProvider to create/update Product variant data to Shopify
    //Update the sync record.
    MappedStockItem obj = bucket.Product;
    ProductData data = null;
    data = await productDataProvider.Create(obj.Extern);
    obj.AddExtern(data, data.Id?.ToString(), data.Title, data.DateModifiedAt.ToDate(false));
    UpdateStatus(obj, operation);
    }

     

Reply