There’s settings in the bartender integration that can trim down the verbosity. You will still have to parse or deserialize the response.
private static void ExecutePrint(StringWriter XML, out string ResponseFirstErrorMessage, out string LastErrorMessage)
{
string ResponseStream = string.Empty;
string BTResponse = string.Empty;
LastErrorMessage = string.Empty;
string JobCompleted = string.Empty;
ResponseFirstErrorMessage = string.Empty;
var webRequest = System.Net.WebRequest.Create(string.Format("http://localhost/Integration/EpicorBartenderIntegration/Execute"));
webRequest.Method = "POST";
webRequest.ContentType = "text/xml";
using (var streamWriter = new System.IO.StreamWriter(webRequest.GetRequestStream()))
{
streamWriter.Write(XML);
streamWriter.Close();
}
try
{
using (HttpWebResponse myHttpWebResponse = (HttpWebResponse)webRequest.GetResponse())
{
using (Stream receiveStream = myHttpWebResponse.GetResponseStream())
{
using (StreamReader readStream = new StreamReader(receiveStream))
{
ResponseStream = readStream.ReadToEnd();
readStream.Close();
}
receiveStream.Close();
}
myHttpWebResponse.Close();
}
BTResponse = GetBetweenTwoWords("ResponseStart", "ResponseEnd", ResponseStream);
LastErrorMessage = GetBetweenTwoWords("LastErrorMessageStart", "LastErrorMessageEnd", ResponseStream);
/*Bartender returns a Response varialble as %response% when it fails sometimes so we check here to make sure what we are getting
is actual XML and not %response% string before we try to load it as xml*/
if (BTResponse != "%Response%")
{
XmlDocument xmlDoc = new XmlDocument();
xmlDoc.LoadXml(BTResponse);
/*Get the job compelted node and value because it seems to denote whether the job completed.*/
var JobCompletedNode = xmlDoc.SelectSingleNode("Response/Command/Print/@JobCompleted");
if(JobCompleted != null)
{
if(JobCompletedNode.InnerText == "false")
{
/*A job can generate multiple messages, I am goign to grab the first meesage that generates a Cancel response since it seems that
the messages that produce cancel responses are the error that causes the print to fail*/
var ResponseFirstErrorMessageNode = xmlDoc.SelectSingleNode("Response/Command/Print/Message[@Response='Cancel']");
if(ResponseFirstErrorMessageNode != null)
{
ResponseFirstErrorMessage = ResponseFirstErrorMessageNode.InnerText;
}
}
}
}
}
catch (System.Net.WebException ex) /*This catch was built to make sure the web service was responding*/
{
MessageBox.Show(ex.Message);
}
}
Additionally you have to understand which responses cause cancellations in printing and which don’t… Some are actual errors, others are looking for user input…
And once you go live 99/100 errors will clear by rebooting Bartender.
At some point, I’ll go back and use the response correctly, but meh. The stack is pretty solid once you get the initial kinks worked out. It just hasn’t been an issue.
I’m with you John, I was fixated on messages in the beginning because there were many, but now that it’s running I have had barely any.
So I tried
outputStr = hwr.GetResponseAsync().ToString();
(Since outputStr is part of the EFx signature there is no need to declare its type.)
And I got this lovely response:
“System.Threading.Tasks.UnwrapPromise`1[System.Net.WebResponse]”
OK, so I’ll need to do a bit more Googling I guess.
as John said above ^^^^^^
And this is where I give up. Alrighty, maybe another day.
IDK, I just assumed if Postman can give me a 200 OK, then there would be a way to get at that in code.
EDIT OK, I see what you were all trying to tell me. I might still get a 200 OK (true, the request went to BT) but have any number of other problems that make the printing action itself fail.
Well that is a big ol’ pain.
It blows me away that I’m told by Support to create an idea rather than being able to user SSRS QR codes, it would save so much complexity and faffing around between multiple programs and introducing more points of failure
people doing all this just for QR codes
Feel free to bump my Idea… https://epicor-manufacturing.ideas.aha.io/ideas/KNTC-I-2461
of other note we had similar issues with some custom made programs by CSG… they had intermittent issues with correctly telling the system something had been generated (even when the “having been generated” was just creating an XML file on their own server… how hard can it be) so could not get “has been printed” to be confirmed correctly.
Michael, that is why Bartender was pushing web service integrations when I spoke to them instead of the file drop integrations.
We’re not even using 2D barcodes. SSRS just gets finicky with label printers sometimes. SSRS also a generalist tool, whereas Bartender is very focused on barcoding. You can get way into the details, setting precise dimensional parameters of elements within a code. SSRS just does barcode fonts, take it or leave it. Bartender is simply a better product for spitting out labels.
I will say the Bartender design and admin apps run like cold garbage and are not that intuitive. However, the biggest hurdle is getting your first integration out the door. After that, it’s wash, rinse, repeat.
Yes.
God Yes, after spending a few weeks fighting my way through SSRS labels I’d love to avoid it, unfortunately our main culprit for generating labels is a custom thing which has not been designed to work with any other system, our other forms we’d like a QR on are just normal forms which it does not make much sense to go outside of SSRS, the QR includes a whole lot of recovery (when enabled) so it is able to bypass many issues caused by faulty printers/supplies
I don’t have any experience with Bartender, but for our relatively simple labeling needs, we’ve integrated with PrintNode using REST calls in functions. I store the labels as ZPL code in a UD table and retrieve it when needed. A new UD field on the Workstation table stores the PrintNode Printer ID, so users can switch between label printers based on workstation.
PrintNode acts as an intermediary between a REST API and our printers, using agents that get installed on a print server or user workstations.
The process goes:
- Button or BPM trigger calls “Barcodes/PrintLabel” function, passing a label name, current workstation ID and any necessary data (part numbers, job numbers, etc).
- Function retrieves the appropriate ZPL label template and replaces place holders (e.g. {partnum}) with the passed values.
- Function calls the PrintNode API, which then sends the ZPL code to the correct printer.
There are free tools out there to help with writing ZPL code; it’s really quite simple.
The result has been a highly flexible, very inexpensive solution for printing basic labels. The fact that this uses a function also means that it’s trivial to add label printing buttons to the UI, especially new Kinetic forms.