I am developing a new processing to process web orders that can be pushed straight through to creating a shipment. I have the process set up that assigns the owner and creates the shipment but I’m not sure how to automatically send the shipment confirmation report to a specific printer on devicehub.
The code I have which works to the point of creating the shipment and storing the shipment number 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;
namespace PPCustomOrderProcess
{
public class AIProcessOrdersCust : PXGraph<AIProcessOrdersCust>
{
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 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<dropShipStart>
>
.And<
SOOrder.status.IsEqual<SOOrderStatus.open>
.Or<
SOOrder.status.IsEqual<SOOrderStatus.awaitingPayment>
>
>
.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 bool PrintShipmentConfirmation(SOShipmentEntry shipmentGraph, string shipmentNbr)
{
bool success = false;
if (string.IsNullOrEmpty(shipmentNbr))
{
throw new PXException("Shipment Number is required for printing.");
}
try
{
////// THIS IS WHERE I AM STUCK ON HOW TO PRINT TO THE PRINTER AUTOMATICALLY //////
PXTrace.WriteInformation($"Shipment Confirmation for {shipmentNbr} has been sent to the printer '{printerName}'.");
success = true;
}
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.");
}
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.Actionso"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.Actionso"CreateShipment"] as PXAction<SOOrder>;
createShipmentAction?.Press();
}
catch (Exception ex)
{
PXTrace.WriteError("Error pressing Create Shipment button: " + ex.Message);
}
}
}
}
Thanks for any advice,
Phil