Printing Customizations#
Estimated time to read: 9 minutes
When and Why to Customize#
The default implementation of the Printing Integration supports HTTP and FTP, and is prepared to handle communication with the NiceLabel and BarTender printing systems. You can also use extended configuration settings for any of these protocols, such as multiple authentication methods or other ways of formatting data. Even more impacting, is the need to use another protocol to interact with a Third-Party Label System. To suppress this problem, you must override the default communication behavior.
Additionally, this page includes a section on the customization of Weigh and Dispense.
Overriding the Web Service Printing Integration#
Using DEE Actions, you can override the way that data is sent and received by changing the main PrintingIntegration class, namely the BuildWebServiceCallback method, responsible for handling the call to the Web Service of the Third-Party Printing System.
The function receives the External Print Data object as an input parameter - with all the information required for the printing operation, and returns a configuration object which contains instructions to call a Web Service using an HTTP Client which will return the output data received by the Third-Party Printing System that can then be returned back to Critical Manufacturing MES for validation.
By using a DEE Action, you can override the Callback function by linking it to BusinessObjects.PrintingIntegration.BuildWebServiceCallback.Post, as shown below:
The DEE Action can access ExternalPrintData and PrintingIntegration, as can be seen in the example below:
UseReference("", "Cmf.Foundation.Common.Exceptions");
//Please start code here
UseReference("Cmf.Navigo.BusinessObjects.dll", "Cmf.Navigo.BusinessObjects.Abstractions");
UseReference("Cmf.Navigo.BusinessObjects.dll", "Cmf.Navigo.BusinessObjects");
UseReference("Cmf.Navigo.BusinessObjects.dll", "Cmf.Navigo.BusinessObjects.Printing.Utils");
UseReference("Cmf.Navigo.Common.dll", "Cmf.Navigo.Common");
UseReference("%MicrosoftNetPath%System.Net.Http.dll", "System.Net.Http");
IPrintingIntegration printingIntegration = Input["PrintingIntegration"] as IPrintingIntegration;
ExternalPrintData externalPrintData = Input["ExternalPrintData"] as ExternalPrintData;
externalPrintData.PrintCallback = (ExternalPrintData printData) =>
{
if (printData == null)
{
throw new ArgumentNullCmfException(nameof(printData));
}
if (string.IsNullOrWhiteSpace(printData.PrinterName))
{
throw new ArgumentNullCmfException(nameof(printData.PrinterName));
}
if (printData.PrintingIntegration == null)
{
throw new ArgumentNullCmfException(nameof(printData.PrintingIntegration));
}
if (string.IsNullOrWhiteSpace(printData.InputDataFromInputRule))
{
throw new ArgumentNullCmfException(
nameof(printData.InputDataFromInputRule));
}
var printingIntegration = printData.PrintingIntegration;
if (string.IsNullOrWhiteSpace(printingIntegration.URL))
{
throw new ArgumentNullCmfException(nameof(printingIntegration.URL));
}
if (printingIntegration.HTTPMethod == null)
{
throw new ArgumentNullCmfException(
nameof(printingIntegration.HTTPMethod));
}
HttpResponseMessage response = null;
if (printingIntegration.HTTPMethod == PrintingSystemHTTPMethod.GET)
{
// transform query parameters to dictionary
string[] keyValuePairs = printData.InputDataFromInputRule.Split('&');
var contentDict = keyValuePairs
.Select(pair => pair.Split('='))
.Where(keyValue => keyValue.Length == 2)
.ToDictionary(keyValue => keyValue[0], keyValue => keyValue[1]);
if (contentDict.Count != keyValuePairs.Length)
{
throw new InvalidPropertyValueCmfException(
printData.InputDataFromInputRule,
nameof(printData.InputDataFromInputRule));
}
response = new PrintingIntegrationWebService().MakeRequest(
HttpMethod.Get,
printingIntegration.URL,
contentDict,
printingIntegration.AuthenticationMethod ?? PrintingSystemAuthenticationMethod.None,
printingIntegration.GetAuthCredentials());
}
else if (printingIntegration.HTTPMethod == PrintingSystemHTTPMethod.POST)
{
if (string.IsNullOrWhiteSpace(printData.ContentTypeFromInputRule))
{
printData.ContentTypeFromInputRule = "application/json";
}
response = new PrintingIntegrationWebService().MakeRequest(
HttpMethod.Post,
printingIntegration.URL,
printData.InputDataFromInputRule,
printData.ContentTypeFromInputRule,
printingIntegration.AuthenticationMethod ?? PrintingSystemAuthenticationMethod.None,
printingIntegration.GetAuthCredentials());
}
printData.OutputData = response?.Content?.ReadAsStringAsync()?.Result;
if (response == null || !response.IsSuccessStatusCode)
{
if (!string.IsNullOrWhiteSpace(printData.OutputData))
{
throw new ErrorOccurredWhenPrintingCmfException(
printData.PrinterName, printData.OutputData);
}
throw new ErrorOccurredWhenPrintingCmfException(printData.PrinterName);
}
return printData.OutputData;
};
Note
This example is illustrated with the default code of the PrintCallback function in the DEE Action that you can change to accommodate your needs.
Overriding the File Printing Integration#
For File Integration the process is the same. The Class PrintingIntegration has the method BuildFileCallback that is responsible for building a function with the instructions to call a Web Service of the Third-Party Printing System. Then, using a DEE Action, you can override the Callback function by linking it to BusinessObjects.PrintingIntegration.BuildFileCallback.Post.
Weigh and Dispense Customization#
By design, Weigh and Dispense sends a list of objects to be printed. However, for external printing, it should only send text. What follows is an example of object parsing in this DEE Action of an Input Formatter Rule:
UseReference("", "Cmf.Foundation.Common.Exceptions");
UseReference("Newtonsoft.Json.dll", "Newtonsoft.Json");
UseReference("Newtonsoft.Json.dll", "Newtonsoft.Json.Linq");
UseReference("%MicrosoftNetPath%System.Text.RegularExpressions.dll", "System.Text.RegularExpressions");
UseReference("%MicrosoftNetPath%System.Private.Xml.dll", "");
UseReference("%MicrosoftNetPath%System.Xml.ReaderWriter.dll", "");
UseReference("%MicrosoftNetPath%System.Web.HttpUtility.dll", "System.Web");
UseReference("", "Cmf.Navigo.BusinessObjects");
if (!Input.ContainsKey("PrintingIntegration") || Input["PrintingIntegration"] == null ||
Input["PrintingIntegration"] is not IPrintingIntegration)
{
throw new ArgumentNullCmfException("PrintingIntegration");
}
if (!Input.ContainsKey("Context") || string.IsNullOrWhiteSpace(Input["Context"]?.ToString()))
{
throw new ArgumentNullCmfException("Context");
}
if (!Input.ContainsKey("PrintObject") ||
(Input["PrintObject"] != null && Input["PrintObject"] is not IEntity))
{
throw new ArgumentNullCmfException("PrintObject");
}
var printIntegration = (IPrintingIntegration)Input["PrintingIntegration"];
string context = Regex.Unescape(Input["Context"].ToString());
var contextDeserialized = JsonConvert.DeserializeObject<Dictionary<string, object>>(context);
// Add Layout, Printer and NumberOfCopies to the context
if (Input.ContainsKey("Layout") && Input["Layout"] is string layout && !string.IsNullOrWhiteSpace(layout))
{
if (contextDeserialized.ContainsKey("Layout"))
{
throw new DataAlreadyExistsCmfException("Context", "Layout");
}
contextDeserialized.Add("Layout", layout);
}
if (Input.ContainsKey("Printer") && Input["Printer"] is string printer && !string.IsNullOrWhiteSpace(printer))
{
if (contextDeserialized.ContainsKey("Printer"))
{
throw new DataAlreadyExistsCmfException("Context", "Printer");
}
contextDeserialized.Add("Printer", printer);
}
if (Input.ContainsKey("NumberOfCopies") && Input["NumberOfCopies"] is int numberOfCopies && numberOfCopies > 0)
{
if (contextDeserialized.ContainsKey("NumberOfCopies"))
{
throw new DataAlreadyExistsCmfException("Context", "NumberOfCopies");
}
contextDeserialized.Add("NumberOfCopies", numberOfCopies.ToString());
}
else
{
throw new ArgumentNullCmfException("NumberOfCopies");
}
// Parse W&D context
if (contextDeserialized.ContainsKey("DispensedEmployees") &&
contextDeserialized["DispensedEmployees"] != null &&
contextDeserialized["DispensedEmployees"] is JArray)
{
var dispensedEmployees = contextDeserialized["DispensedEmployees"] as JArray;
string dispensedEmployeesStr = string.Empty;
for (var i = 0; i < dispensedEmployees.Count; i++)
{
var employee = dispensedEmployees[0] as JObject;
if (employee != null)
{
if (dispensedEmployeesStr != string.Empty)
{
dispensedEmployeesStr += ", ";
}
dispensedEmployeesStr += employee["Name"];
}
}
contextDeserialized["DispensedEmployees"] = dispensedEmployeesStr;
}
if (contextDeserialized.ContainsKey("DispensedFromMaterials") &&
contextDeserialized["DispensedFromMaterials"] != null &&
contextDeserialized["DispensedFromMaterials"] is JArray)
{
var dispensedFromMaterials = contextDeserialized["DispensedFromMaterials"] as JArray;
string dispensedFromMaterialsStr = string.Empty;
for (var i = 0; i < dispensedFromMaterials.Count; i++)
{
var material = dispensedFromMaterials[0] as JObject;
if (material != null)
{
if (dispensedFromMaterialsStr != string.Empty)
{
dispensedFromMaterialsStr += ", ";
}
dispensedFromMaterialsStr += material["Name"];
}
}
contextDeserialized["DispensedFromMaterials"] = dispensedFromMaterialsStr;
}
if (contextDeserialized.ContainsKey("DispensedToMaterials") &&
contextDeserialized["DispensedToMaterials"] != null &&
contextDeserialized["DispensedToMaterials"] is JArray)
{
var dispensedToMaterials = contextDeserialized["DispensedToMaterials"] as JArray;
string dispensedToMaterialsStr = string.Empty;
for (var i = 0; i < dispensedToMaterials.Count; i++)
{
var material = dispensedToMaterials[0] as JObject;
if (material != null)
{
if (dispensedToMaterialsStr != string.Empty)
{
dispensedToMaterialsStr += ", ";
}
dispensedToMaterialsStr += material["Name"];
}
}
contextDeserialized["DispensedToMaterials"] = dispensedToMaterialsStr;
}
if (contextDeserialized.ContainsKey("DispensedFromContainers") &&
contextDeserialized["DispensedFromContainers"] != null &&
contextDeserialized["DispensedFromContainers"] is JArray)
{
var dispensedFromContainers = contextDeserialized["DispensedFromContainers"] as JArray;
string dispensedFromContainersStr = string.Empty;
for (var i = 0; i < dispensedFromContainers.Count; i++)
{
var container = dispensedFromContainers[0] as JObject;
if (container != null)
{
if (dispensedFromContainersStr != string.Empty)
{
dispensedFromContainersStr += ", ";
}
dispensedFromContainersStr += container["Name"];
}
}
contextDeserialized["DispensedFromContainers"] = dispensedFromContainersStr;
}
if (contextDeserialized.ContainsKey("DispensedToContainers") &&
contextDeserialized["DispensedToContainers"] != null &&
contextDeserialized["DispensedToContainers"] is JArray)
{
var dispensedToContainers = contextDeserialized["DispensedToContainers"] as JArray;
string dispensedToContainersStr = string.Empty;
for (var i = 0; i < dispensedToContainers.Count; i++)
{
var container = dispensedToContainers[0] as JObject;
if (container != null)
{
if (dispensedToContainersStr != string.Empty)
{
dispensedToContainersStr += ", ";
}
dispensedToContainersStr += container["Name"];
}
}
contextDeserialized["DispensedToContainers"] = dispensedToContainersStr;
}
if (contextDeserialized.ContainsKey("DispensedFromProducts") &&
contextDeserialized["DispensedFromProducts"] != null &&
contextDeserialized["DispensedFromProducts"] is JArray)
{
var dispensedFromProducts = contextDeserialized["DispensedFromProducts"] as JArray;
string dispensedFromProductsStr = string.Empty;
for (var i = 0; i < dispensedFromProducts.Count; i++)
{
var product = dispensedFromProducts[0] as JObject;
if (product != null)
{
if (dispensedFromProductsStr != string.Empty)
{
dispensedFromProductsStr += ", ";
}
dispensedFromProductsStr += product["Name"];
}
}
contextDeserialized["DispensedFromProducts"] = dispensedFromProductsStr;
}
if (contextDeserialized.ContainsKey("DispensedToProducts") &&
contextDeserialized["DispensedToProducts"] != null &&
contextDeserialized["DispensedToProducts"] is JArray)
{
var dispensedToProducts = contextDeserialized["DispensedToProducts"] as JArray;
string dispensedToProductsStr = string.Empty;
for (var i = 0; i < dispensedToProducts.Count; i++)
{
var product = dispensedToProducts[0] as JObject;
if (product != null)
{
if (dispensedToProductsStr != string.Empty)
{
dispensedToProductsStr += ", ";
}
dispensedToProductsStr += product["Name"];
}
}
contextDeserialized["DispensedToProducts"] = dispensedToProductsStr;
}
if (contextDeserialized.ContainsKey("DispensedFromSteps") &&
contextDeserialized["DispensedFromSteps"] != null &&
contextDeserialized["DispensedFromSteps"] is JArray)
{
var dispensedFromSteps = contextDeserialized["DispensedFromSteps"] as JArray;
string dispensedFromStepsStr = string.Empty;
for (var i = 0; i < dispensedFromSteps.Count; i++)
{
var step = dispensedFromSteps[0] as JObject;
if (step != null)
{
if (dispensedFromStepsStr != string.Empty)
{
dispensedFromStepsStr += ", ";
}
dispensedFromStepsStr += step["Name"];
}
}
contextDeserialized["DispensedFromSteps"] = dispensedFromStepsStr;
}
if (contextDeserialized.ContainsKey("DispensedToSteps") &&
contextDeserialized["DispensedToSteps"] != null &&
contextDeserialized["DispensedToSteps"] is JArray)
{
var dispensedToSteps = contextDeserialized["DispensedToSteps"] as JArray;
string dispensedToStepsStr = string.Empty;
for (var i = 0; i < dispensedToSteps.Count; i++)
{
var step = dispensedToSteps[0] as JObject;
if (step != null)
{
if (dispensedToStepsStr != string.Empty)
{
dispensedToStepsStr += ", ";
}
dispensedToStepsStr += step["Name"];
}
}
contextDeserialized["DispensedToSteps"] = dispensedToStepsStr;
}
if (contextDeserialized.ContainsKey("DispensedMethods") &&
contextDeserialized["DispensedMethods"] != null &&
contextDeserialized["DispensedMethods"] is JArray)
{
var dispensedMethods = contextDeserialized["DispensedMethods"] as JArray;
string dispensedMethodsStr = string.Empty;
for (var i = 0; i < dispensedMethods.Count; i++)
{
var method = (dispensedMethods[0] as JToken)?.ToString();
if (method != null)
{
if (dispensedMethodsStr != string.Empty)
{
dispensedMethodsStr += ", ";
}
dispensedMethodsStr += method;
}
}
contextDeserialized["DispensedMethods"] = dispensedMethodsStr;
}
if (contextDeserialized.ContainsKey("DispensedQuantities") &&
contextDeserialized["DispensedQuantities"] != null &&
contextDeserialized["DispensedQuantities"] is JArray)
{
var dispensedQuantities = contextDeserialized["DispensedQuantities"] as JArray;
string dispensedQuantitiesStr = string.Empty;
for (var i = 0; i < dispensedQuantities.Count; i++)
{
var quantity = (dispensedQuantities[0] as JToken)?.ToString();
if (quantity != null)
{
if (dispensedQuantitiesStr != string.Empty)
{
dispensedQuantitiesStr += ", ";
}
dispensedQuantitiesStr += quantity;
}
}
contextDeserialized["DispensedQuantities"] = dispensedQuantitiesStr;
}
if (contextDeserialized.ContainsKey("DispensedResources") &&
contextDeserialized["DispensedResources"] != null &&
contextDeserialized["DispensedResources"] is JArray)
{
var dispensedResources = contextDeserialized["DispensedResources"] as JArray;
string dispensedResourcesStr = string.Empty;
for (var i = 0; i < dispensedResources.Count; i++)
{
var resource = dispensedResources[0] as JObject;
if (resource != null)
{
if (dispensedResourcesStr != string.Empty)
{
dispensedResourcesStr += ", ";
}
dispensedResourcesStr += resource["Name"];
}
}
contextDeserialized["DispensedResources"] = dispensedResourcesStr;
}
if (contextDeserialized.ContainsKey("DispensedScales") &&
contextDeserialized["DispensedScales"] != null &&
contextDeserialized["DispensedScales"] is JArray)
{
var dispensedScales = contextDeserialized["DispensedScales"] as JArray;
string dispensedScalesStr = string.Empty;
for (var i = 0; i < dispensedScales.Count; i++)
{
var scale = dispensedScales[0] as JObject;
if (scale != null)
{
if (dispensedScalesStr != string.Empty)
{
dispensedScalesStr += ", ";
}
dispensedScalesStr += scale["Name"];
}
}
contextDeserialized["DispensedScales"] = dispensedScalesStr;
}
if (contextDeserialized.ContainsKey("DispensedTares") &&
contextDeserialized["DispensedTares"] != null &&
contextDeserialized["DispensedTares"] is JArray)
{
var dispensedTares = contextDeserialized["DispensedTares"] as JArray;
string dispensedTaresStr = string.Empty;
for (var i = 0; i < dispensedTares.Count; i++)
{
var tare = (dispensedTares[0] as JToken)?.ToString();
if (tare != null)
{
if (dispensedTaresStr != string.Empty)
{
dispensedTaresStr += ", ";
}
dispensedTaresStr += tare;
}
}
contextDeserialized["DispensedTares"] = dispensedTaresStr;
}
if (contextDeserialized.ContainsKey("DispensedToContainerTypes") &&
contextDeserialized["DispensedToContainerTypes"] != null &&
contextDeserialized["DispensedToContainerTypes"] is JArray)
{
var dispensedToContainerTypes = contextDeserialized["DispensedToContainerTypes"] as JArray;
string dispensedToContainerTypesStr = string.Empty;
for (var i = 0; i < dispensedToContainerTypes.Count; i++)
{
var containerType = (dispensedToContainerTypes[0] as JToken)?.ToString();
if (containerType != null)
{
if (dispensedToContainerTypesStr != string.Empty)
{
dispensedToContainerTypesStr += ", ";
}
dispensedToContainerTypesStr += containerType;
}
}
contextDeserialized["DispensedToContainerTypes"] = dispensedToContainerTypesStr;
}
if (contextDeserialized.ContainsKey("DispensedUnits") &&
contextDeserialized["DispensedUnits"] != null &&
contextDeserialized["DispensedUnits"] is JArray)
{
var dispensedUnits = contextDeserialized["DispensedUnits"] as JArray;
string dispensedUnitsStr = string.Empty;
for (var i = 0; i < dispensedUnits.Count; i++)
{
var unit = (dispensedUnits[0] as JToken)?.ToString();
if (unit != null)
{
if (dispensedUnitsStr != string.Empty)
{
dispensedUnitsStr += ", ";
}
dispensedUnitsStr += unit;
}
}
contextDeserialized["DispensedUnits"] = dispensedUnitsStr;
}
context = JsonConvert.SerializeObject(contextDeserialized);
var Output = new Dictionary<string, object>();
var result = new Dictionary<string, object>();
if (printIntegration.HTTPMethod == null)
{
throw new ArgumentNullCmfException(nameof(printIntegration.HTTPMethod));
}
if (printIntegration.HTTPMethod == Cmf.Navigo.BusinessObjects.PrintingSystemHTTPMethod.POST)
{
var contentType = printIntegration.WebServiceContentType;
if (contentType == null)
{
throw new ArgumentNullCmfException(nameof(printIntegration.WebServiceContentType));
}
else if (contentType == Cmf.Navigo.BusinessObjects.PrintingSystemWebServiceContentType.JSON)
{
result.Add("Content", context);
}
else if (contentType == Cmf.Navigo.BusinessObjects.PrintingSystemWebServiceContentType.XML)
{
System.Xml.XmlDocument document = JsonConvert.DeserializeXmlNode(context, "Content");
result.Add("Content", document.OuterXml);
}
else
{
throw new NotImplementedException($"The {nameof(printIntegration.WebServiceContentType)} is not supported.");
}
}
else if (printIntegration.HTTPMethod == Cmf.Navigo.BusinessObjects.PrintingSystemHTTPMethod.GET)
{
var contextDict = JsonConvert.DeserializeObject<Dictionary<string, object>>(context);
var queryParameters = string.Join(
"&",
contextDict.Select(kvp => $"{HttpUtility.UrlEncode(kvp.Key)}={HttpUtility.UrlEncode(kvp.Value?.ToString() ?? string.Empty)}"));
result.Add("Content", queryParameters);
}
else
{
throw new NotImplementedException($"The {nameof(printIntegration.HTTPMethod)} is not supported.");
}
Output.Add("Result", result);
return Output;
