How can I invoke File Synchonization Action via code (SM202530)

We’re using file synchronization to send payment batch files to an external site. File Synchronization only works on a per file basis so we have set up one file that our export scenario will populate.

Because we need every version of this file to be sent to the external site, I need to make sure that every revision of the file is synchronized.

My thought was to override the Export button on Batch Payments (AP305000) to call the Process All Files action, using the Export File operation, on the File Synchronization screen. The challenge is that I can’t see to find the name of the graph to instantiate to access that business object.

Here is where I’m at:

using System;
using System.Collections;
using System.Collections.Generic;
using System.Linq;
using PX.Api;
using PX.Data;
using PX.Data.WorkflowAPI;
using PX.Objects.AP;
using PX.Objects.AR;
using PX.Objects.CM;
using PX.Objects.Common.Extensions;
using PX.Objects.CR;
using PX.Objects.CS;
using PX.Objects.GL;
using PX.Objects.AP.MigrationMode;
using PX.Objects;
using PX.Objects.CA;
using PX.Objects.SM;

namespace PX.Objects.CA
{
  public class CABatchEntry_Extension : PXGraphExtension<CABatchEntry>
  {

    [PXOverride]
    public virtual IEnumerable Export(PXAdapter adapter)
    {

      Base.export.Press(adapter);

      //Challenge is here
      SynchronizationProcess docgraph = PXGraph.CreateInstance<SynchronizationProcess>();

      foreach (var action in (docgraph.action.GetState(null) as PXButtonState).Menus)
      {
        if (action.Command == "Process All Files")
        {
          PXAdapter adapter2 = new PXAdapter(new DummyView(docgraph, docgraph.Document.View.BqlSelect, new List<object> { docgraph.Document.Current }));
          adapter2.Menu = action.Command;
          docgraph.action.PressButton(adapter2);

          TimeSpan timespan;
          Exception ex;
          while (PXLongOperation.GetStatus(docgraph.UID, out timespan, out ex) == PXLongRunStatus.InProcess)
          { }
          break;
        }
      }
      return adapter.Get();
    }

    internal class DummyView : PXView
    {
      List<object> _Records;
      internal DummyView(PXGraph graph, BqlCommand command, List<object> records)
               : base(graph, true, command)
      {
        _Records = records;
      }
      public override List<object> Select(object[] currents, object[] parameters, object[] searches, string[] sortcolumns, bool[] descendings, PXFilterRow[] filters, ref int startRow, int maximumRows, ref int totalRows)
      {
        return _Records;
      }
    }

  }
}

You can write your own PXLongOperation which will invoke the Processing Delegate the same way that page does, like below. Then you can use PXLongOperation.WaitCompletion(this.Base.UID) to wait till the process is completed and then do any other actions that you need to do.

public PXAction<SOOrder> RunSynchronization;

[PXButton(CommitChanges = true)]
[PXUIField(DisplayName = "Sync Files")]
protected IEnumerable runSynchronization(PXAdapter adapter)
{
    PXLongOperation.StartOperation(this.Base, () =>
    {
        SynchronizationProcess docgraph = PXGraph.CreateInstance<SynchronizationProcess>();
        docgraph.filter.SetValueExt<SynchronizationFilter.operation>(docgraph.filter.Current,"U"); //U - export D - import
        var records = docgraph.SelectedFiles.Select().RowCast<UploadFileWithIDSelector>().ToList();
        docgraph.SelectedFiles.GetProcessDelegate().DynamicInvoke(records);
    });
    return adapter.Get();
}

Leave a Comment