Skip to main content
Solved

How can I create a selector that lists all printers available via the devicehub at the top of a new processing screen?


Forum|alt.badge.img+1

I have the following code set up which prints to a specific hard coded printer name on the devicehub. I’m stumped as to how to create the selector to get a list of printers from the devicehub.  This is what I have so far which doesn’t work correctly as clicking on the selector gives an error: Object reference not set to an instance of an object.

 

The code is below:

using System;
using PX.Data;
using PX.Objects.SO;
using PX.Data.BQL.Fluent;
using PX.TM;
using PX.Common;
using System.Collections.Generic;
using PX.Objects.CR;
using PX.SM;
using PX.Reports;
using System.Threading.Tasks;
using System.Threading;

namespace PPCustomOrderProcess
{

  public class AIProcessOrdersCust : PXGraph<AIProcessOrdersCust>
  {

    [PXString]
    [PXUIField(DisplayName = "Printer")]
    [PXSelector(
        typeof(Search<SMPrinter.printerID>),
        typeof(SMPrinter.printerName),
        typeof(SMPrinter.description),
        SubstituteKey = typeof(SMPrinter.printerName),
        DescriptionField = typeof(SMPrinter.description))]
    public virtual Guid? SelectedPrinter { get; set; }
    public abstract class selectedPrinter : PX.Data.BQL.BqlGuid.Field<selectedPrinter> { }

    public class wOOrderType: PX.Data.BQL.BqlString.Constant<wOOrderType> {
      public wOOrderType() : base("WO") { }
    }

    public class paymentMethodAFFIRM: PX.Data.BQL.BqlString.Constant<paymentMethodAFFIRM> {
      public paymentMethodAFFIRM() : base("AFFIRM") { }
    }

    public class paymentMethodAFTERPAY: PX.Data.BQL.BqlString.Constant<paymentMethodAFTERPAY> {
      public paymentMethodAFTERPAY() : base("AFTERPAY") { }
    }

    public class paymentMethodPAYPAL: PX.Data.BQL.BqlString.Constant<paymentMethodPAYPAL> {
      public paymentMethodPAYPAL() : base("PAYPAL") { }
    }

    public class paymentMethodCCARD: PX.Data.BQL.BqlString.Constant<paymentMethodCCARD> {
      public paymentMethodCCARD() : base("CCARD") { }
    }

    public class dropShipStart: PX.Data.BQL.BqlString.Constant<dropShipStart> {
      public dropShipStart() : base("DS%") { }
    }

    public class signatureWaived: PX.Data.BQL.BqlString.Constant<signatureWaived> {
      public signatureWaived() : base("%SIGNATURE WAIVED%") { }
    }

    public class intlShipVia: PX.Data.BQL.BqlString.Constant<intlShipVia> {
      public intlShipVia() : base("%intl%") { }
    }

    public class orderTotalMaxSpend: PX.Data.BQL.BqlDecimal.Constant<orderTotalMaxSpend> {
      public orderTotalMaxSpend() : base(500m) { }
    }

    public PXCancel<SOOrder> Cancel;

  // Create an alias for clarity
  public class OuterSOOrder : SOOrder { }

  public SelectFrom<SOOrder>
    .LeftJoin<Note>.On<SOOrder.noteID.IsEqual<Note.noteID>>
    .Where<
        SOOrder.orderType.IsEqual<wOOrderType>
        .And<
          SOOrder.shipVia.IsNotLike<intlShipVia>
        >
        .And<
          SOOrder.shipVia.IsNotLike<dropShipStart>
        >
        .And<
          SOOrder.status.IsEqual<SOOrderStatus.open>
        >
        .And<
          Note.noteID.IsNull
          .Or<Note.noteText.IsNull>
          .Or<Note.noteText.IsEqual<Empty>>
          .Or<Note.noteText.IsLike<signatureWaived>>
        >
        .And<
          SOOrder.curyOrderTotal.IsLessEqual<orderTotalMaxSpend>
        >
        .And<
            SOOrder.paymentMethodID.IsEqual<paymentMethodAFFIRM>
            .Or<SOOrder.paymentMethodID.IsEqual<paymentMethodPAYPAL>>
            .Or<SOOrder.paymentMethodID.IsEqual<paymentMethodAFTERPAY>>
            .Or<
                SOOrder.paymentMethodID.IsEqual<paymentMethodCCARD>
                .And<
                    Exists<SelectFrom<SOOrder>
                        .Where<
                            SOOrder.paymentMethodID.IsEqual<paymentMethodCCARD>
                            .And<
                                SOOrder.customerID.IsEqual<OuterSOOrder.customerID>
                            >
                            .And<
                                SOOrder.status.IsEqual<SOOrderStatus.shipping> // Change shipping to completed before final publish
                            >
                        >
                    >
                >
            >
        >
    >
    .ProcessingView AISOOrder;


    public AIProcessOrdersCust()
    {
      AISOOrder.SetProcessCaption("Assign");
      AISOOrder.SetProcessAllCaption("Assign All");

      AISOOrder.SetProcessDelegate(ProcessOrder);
    }

    public PXFilter<DetailsTable> DetailsView;

    [Serializable]
    public class DetailsTable : IBqlTable
    {

    }

    /// <summary>
    /// Processing Method to Assign Owner to Logged-in User
    /// </summary>
    private static void ProcessOrder(SOOrder order)
    {
        var graph = PXGraph.CreateInstance<SOOrderEntry>();

        // Select the order
        graph.Document.Current = graph.Document.Search<SOOrder.orderNbr>(order.OrderNbr, order.OrderType);

        if (graph.Document.Current != null)
        {
            int? currentUserContactID = PXAccess.GetContactID();
            if (currentUserContactID != null)
            {
                graph.Document.Cache.SetValueExt<SOOrder.ownerID>(graph.Document.Current, currentUserContactID);
                graph.Document.Cache.MarkUpdated(graph.Document.Current);

                // Log the new OwnerID for verification
                PXTrace.WriteInformation($"Setting OwnerID to {currentUserContactID} for Order {order.OrderNbr}");

                // Save the changes
                graph.Actions.PressSave();

                // Create a shipment for the order

                bool shipmentCreated = CreateShipmentFromButton(graph);

                // Confirm the shipmnent is created before pressing the new button

                if (shipmentCreated)
                {
                    // Retrieve the Shipment Number
                    var shipmentNbr = GetShipmentNumber(order);

                    if (!string.IsNullOrEmpty(shipmentNbr))
                    {
                      // Load shipment graph and print the shipment confirmation
                      var shipmentGraph = PXGraph.CreateInstance<SOShipmentEntry>();
                      var shipment = shipmentGraph.Document.Search<SOShipment.shipmentNbr>(shipmentNbr);

                      if (shipment != null)
                      {
                        bool printedShipmentConfirmation = PrintShipmentConfirmation(shipmentGraph, shipmentNbr);

                        if (printedShipmentConfirmation)
                        {
                          PXProcessing<SOOrder>.SetInfo($"Order {order.OrderNbr} successfully assigned to user with ContactID: {currentUserContactID} and shipment {shipmentNbr} printed.");
                        }
                        else
                        {
                          PXProcessing<SOOrder>.SetInfo($"Order {order.OrderNbr} successfully assigned to user with ContactID: {currentUserContactID} and shipment {shipmentNbr} created but not printed.");
                        }
                      }
                      else
                      {
                        PXProcessing<SOOrder>.SetError($"Order {order.OrderNbr} successfully assigned to user with ContactID: {currentUserContactID}, but shipment could not be retrieved to print.");
                      }
                    }
                    else
                    {
                        PXProcessing<SOOrder>.SetWarning($"Shipment created, but no shipment number found for Order {order.OrderNbr}.");
                    }
                }
                else
                {
                    PXProcessing<SOOrder>.SetError($"Order {order.OrderNbr} successfully assigned to user with ContactID: {currentUserContactID}, but shipment could not be created.");
                }
            }
            else
            {
                PXProcessing<SOOrder>.SetError($"Failed to assign OwnerID: No ContactID found for current user.");
            }
        }
        else
        {
            PXProcessing<SOOrder>.SetError($"Order {order.OrderNbr} not found.");
        }
    }


    private static Guid GetPrinterIdByName(string printerName, PXGraph printGraph)
    {
        // Query the SMPrinter table for a printer with the specified printerName
        var printer = PXSelect<SMPrinter,
                                Where<SMPrinter.printerName, Equal<Required<SMPrinter.printerName>>>>.Select(printGraph, printerName);

        if (printer != null && printer.Count > 0)
        {
            SMPrinter smPrinter = printer[0];

            if (smPrinter.PrinterID.HasValue)
            {
                return smPrinter.PrinterID.Value; // Return the PrinterID as a non-nullable Guid
            }
            else
            {
                // Handle the case where PrinterID is null
                throw new Exception($"Printer '{printerName}' has a null PrinterID.");
            }
        }

        // Handle the case where the printer wasn't found
        throw new Exception($"Printer '{printerName}' not found.");
    }

    private static bool PrintShipmentConfirmation(SOShipmentEntry shipmentGraph, string shipmentNbr)
    {
      bool success = false;

      if (string.IsNullOrEmpty(shipmentNbr))
      {
        throw new PXException("Shipment Number is required for printing.");
      }

      try
      {
          const string reportID = "SO642000";
          const string description = "Shipment Confirmation";

          var parametersDictionary = new Dictionary<string, string>
          {
              { "ShipmentNbr", shipmentNbr },
              // Add other parameters if necessary
          };

          PXGraph printGraph = PXGraph.CreateInstance<SMPrintJobMaint>();
          // Step 2: Define the print settings
          PrintSettings printSettings = new PrintSettings()
          {
              PrinterID = GetPrinterIdByName("W2PDFHUB", printGraph), // Replace with logic to get the default printer ID
              //PrinterID = printerID,
              NumberOfCopies = 1,
              PrintWithDeviceHub = true,
              DefinePrinterManually = true
          };

          // Step 3: Create the print job
          PXGraph.CreateInstance<SMPrintJobMaint>().CreatePrintJob(printSettings, reportID, parametersDictionary, "Shipment Confirmation", CancellationToken.None);

          // Log or handle any post-print actions
          PXTrace.WriteInformation("Shipment Confirmation print job initiated.");

      }
      catch (Exception ex)
      {
          PXTrace.WriteError($"Failed to print Shipment Confirmation for {shipmentNbr}. Error: {ex.Message}");
          throw new PXException($"Failed to print Shipment Confirmation for {shipmentNbr}. Please check the printer configuration.");
      }
      finally
      {
        success = true;
      }

      return success;
    }

    /// <summary>
    /// Retrieves the Shipment Number associated with the order.
    /// </summary>
    private static string GetShipmentNumber(SOOrder order)
    {
        var shipment = PXSelect<SOOrderShipment,
            Where<SOOrderShipment.orderType, Equal<Required<SOOrderShipment.orderType>>,
                And<SOOrderShipment.orderNbr, Equal<Required<SOOrderShipment.orderNbr>>>>>
            .SelectWindowed(new PXGraph(), 0, 1, order.OrderType, order.OrderNbr);

        return shipment != null ? ((SOOrderShipment)shipment).ShipmentNbr : null;
    }

    private static bool CreateShipmentFromButton(SOOrderEntry graph)
    {

          // Trigger the "Create Shipment" action on the graph (simulate button click)
          PXAction<SOOrder> createShipmentAction = graph.Actions["CreateShipment"] as PXAction<SOOrder>;
          if (createShipmentAction != null)
          {
              // If the button exists, press it programmatically
              PXTrace.WriteInformation($"Pressing button for create shipment");

              createShipmentActionPress(graph);

              return true;
          }
          else
          {
              PXTrace.WriteError("Create Shipment action not found.");
          }
          return false;

    }

    private static void createShipmentActionPress(SOOrderEntry graph)
    {
        try
        {
            PXAction<SOOrder> createShipmentAction = graph.Actions["CreateShipment"] as PXAction<SOOrder>;
            createShipmentAction?.Press();
        }
        catch (Exception ex)
        {
            PXTrace.WriteError("Error pressing Create Shipment button: " + ex.Message);
        }
    }

  }
}

 

Best answer by Django

I wonder if you need to change your declaration from

[PXString]

to

[PXGuid]

The APTran.cs file has the Custodian field which is using EPEmployee.userID like you’re using PrinterID

View original
Did this topic help you find an answer to your question?

2 replies

Forum|alt.badge.img+6
  • Captain II
  • 550 replies
  • Answer
  • January 9, 2025

I wonder if you need to change your declaration from

[PXString]

to

[PXGuid]

The APTran.cs file has the Custodian field which is using EPEmployee.userID like you’re using PrinterID


Forum|alt.badge.img+1
  • Author
  • Semi-Pro I
  • 134 replies
  • January 11, 2025

@Django Thanks.  That was really helpful.  I ended up changing to a Guid but also needed to add a PXFilter :

public PXFilter<PrinterFilter> PrinterView;

    [Serializable]
    public class PrinterFilter : IBqlTable
    {
        #region PrinterID
        [PXGuid]
        [PXUIField(DisplayName = "Printer")]
        [PXSelector(
            typeof(Search<SMPrinter.printerID>),  // Assuming printerID is the GUID field
            typeof(SMPrinter.printerName),
            typeof(SMPrinter.description),
            SubstituteKey = typeof(SMPrinter.printerName),
            DescriptionField = typeof(SMPrinter.description),
            DirtyRead = true)]
        public virtual Guid? PrinterID { get; set; }
        public abstract class printerID : PX.Data.BQL.BqlGuid.Field<printerID> { }
        #endregion
    }

Once I added that to the screen I could select a printer.

 

Thanks for your help,

 

Phil


Reply


Cookie policy

We use cookies to enhance and personalize your experience. If you accept you agree to our full cookie policy. Learn more about our cookies.

 
Cookie settings