Print Part Attachments When Mass Printing Job Travelers

CodaBears has a Job Packet Print Utility that looks like it will print the attachments with the Travelers. It looks like it can select the jobs marked for Mass Print. No, I don’t work for CodaBears. :slight_smile: We are having them do some work for us and I happened to see it on their website:
http://www.codabears.com/Products/JobPacketPrint.aspx
We don’t currently use the utility, but it looks like a useful tool.
We earlier looked into using APM/APM+ to do this, but we didn’t want to have to copy all of the part attachments to the APM repository. The newer versions of APM+ might be able to print external documents that aren’t in the APM repository.

Thanks for all the info y’all, very helpful.

C# Customization - My coworker and I do some coding here, but don’t have coding backgrounds (ie. we’re not very good at it). Bitman, or anyone else with experience, is doing this via custom code pretty involved or would it be possible for mediocre coders?

Crystal Report - May be a good band-aid solution. Our drawings are auto-exported out of SolidWorks as PDFs into a folder, then DMTd into Epicor daily. PDFs don’t work well as OLE Objects. I’m guessing we could auto-export as PNGs as well and insert these as OLE Objects. Are there issues/concerns beyond this? What does “Using the OLE objects…will not work very well except in a limited fashion mean”?

3rd Party Application - Seems like there are a few companies that do this. Would be a bit wasteful though if you’re planning on eventually doing APM/APM+. How have experiences been with CodaBears, Dot Net, and any of the other companies that provide this solution whether you used them for this solution or something else?

APM/APM+ - Will try and research whether newer versions can print external documents that aren’t in the APM repository. That seems like a function that could be useful here and beyond this application.

Copy/Print Machines - Don’t think we have a machine or a service organization like that, but that’s an interesting idea.

Tyler,
If you think you have enough coding skills to take our existing code and adapt it to fit your environment, I can share it with you. Just as you, we export our Solidworks drawings to pdf, but from what I understand you then import the pdf in your database. That is the part you would have to change because we only store file path (DocType = attachment link) in Epicor. Our code retrieves the path to the pdf file from the part revision attachment table and prints the file from the shared folder.

Yea could you upload the code on this thread? I don’t know if we’ll be able to adapt it, but sure as hell would be easier than starting from scratch.

This is something we have struggled with for quite a long time. Would love
to see your code as well Bitman.

Thanks,

Norman Hutchins
Systems Administrator
Howell Laboratories, Inc.

Ok for those interested, here’s how it works:
(As english is not my native language, sorry if I make mistakes. I will try to describe the solution clearly.) Feel free to ask clarification if needed.

We use the Autovue program to print the files. We can pass command lines arguments to have it read a text file which contains the paths of files we want to print.
We use UD fields in the company table (shortchar04 and 05) to define the autovue executable path and the text file location on the workstation.
We added a customization to the job traveler screen, added a button in the report options section and add the code to this customization. The user selects the jobs in the filter, prints the job traveler and click the button to print the drawings. Job travelers and drawings will need to be matched after printing is done.

The code connects to the JobEntry BO to retrieve the attachments links from the JobAsmblAttch table, based on the DocType we want. We store this information in a temp table so we can filter out the duplicates (we don’t want to print a drawing more than once), and then we generates the text file on the workstation, one path per line. Finallly, we send a command to have autovue read the file and print each path stored in it.

Probably not the best solution, but this is working well for us, hope it can help some of you. Find the code attached.

print_Job_attachments.cs (7.9 KB)

Thanks Bitman. Looks pretty involved, so we’re going to start by trying a Crystal Report with OLE Objects. Will let the group know if that works out.

Dot Net has a Job Traveler Solution that worked great for us in Epicor 9.05.702. They uplifted it to 10.1.500, but we have not installed it fully yet. I believe they merged with Epicor now. I found this link out there http://www.dotnetit.co.uk/solutions/solution/job-traveller

Hi Bitman,

My name is Alex and I would like to thank you for sharing information on this challenge as I found it very useful in my case. However, as I am very new to Epicor system and a very Junior in programming, not everything is obvious to me. Is it possible to communicate with you and clarify a couple of moments?

Or if you could just explain what are those values or rather where are they coming from (“ENGRLINK”, “DRAWLINK”, “INSTR”) you are checking for in the follow part of code that would be wonderful as well.

“if(asar[“DocTypeID”].ToString() == “ENGRLINK” || asar[“DocTypeID”].ToString() == “DRAWLINK” || asar[“DocTypeID”].ToString() == “INSTR”)”

Any help would be much appreciated!

You can contact me here:
odniprovskyi@hotmail.com
Time Zone is EST.

Thank you,

Alex

Please keep the communication on the site for the benefit of everyone.

Hi Jose,

I ma not trying to hide anything or be selfish I just need to ask the person couple clarification questions, that’s it and also I have modified my reply.

I am new to the community so will learn a long the way.

Thanks,

Alex

@AlexD
Those are document types as setup in the Document Type Maintenance
image

Hi Alex,

Like Jose said, these are Document types we have defined in the DocType table. ENGRLINK stands for Engineering Link, DRAWLINK is for our technical drawings, you get the idea…

If you have any more question, feel free to post it, I will be glad to help if I can.

Christian

Hey guys,

I have tried some stuff for the last couple days but couldn’t get anything sufficient. The thing is we do not have any Document Types set up as well as not using any third party apps to print Jobs in Job Traveler.

However, I traced some logs when printed a preview and found next:

    <JobHead>
      <JobClosed>false</JobClosed>
      <ClosedDate>2017-07-24T00:00:00-04:00</ClosedDate>
      <JobComplete>false</JobComplete>
      <JobEngineered>true</JobEngineered>
      <CheckOff1>false</CheckOff1>
      <CheckOff2>false</CheckOff2>
      <CheckOff3>false</CheckOff3>
      <CheckOff4>false</CheckOff4>
      <CheckOff5>false</CheckOff5>
      <JobReleased>true</JobReleased>
      <JobHeld>true</JobHeld>
      <SchedStatus>R</SchedStatus>
      <JobNum>064302</JobNum>
      <PartNum>M0161</PartNum>
      <RevisionNum>B</RevisionNum>
      <DrawNum></DrawNum>
      <PartDescription>1224 headstock machining</PartDescription>
      **And a bunch of XYZ info from JobHead Table printed.........**
    </JobHead>

Here I found some interesting stuff:

    <JobHeadAttch>
      <Company>xyz</Company>
      <JobNum>064302</JobNum>
      <DrawingSeq>9670</DrawingSeq>
      <XFileRefNum>1910</XFileRefNum>
      <SysRevID>54175122</SysRevID>
      <SysRowID>292b0a6e-5569-4b46-9ba7-88a001e7c63f</SysRowID>
      <ForeignSysRowID>7357bd7b-1fa4-4796-a74b-8645c53e830f</ForeignSysRowID>
      <DrawDesc>M0161 headstock.dft</DrawDesc>
      <FileName>N:\Drawing Files\12in mini\M0161 headstock.dft</FileName>
      <PDMDocID></PDMDocID>
      <DocTypeID></DocTypeID>
      <RowMod></RowMod>
    </JobHeadAttch>

JobHeadAttch table is not in DB and I assume it’s a temp table that is created while a printing preview process is in action (I might be wrong here though).

Do you know guys if there is a way to set up a scenario like:

  1. Place a custom button on a JobTravaler screen.
  2. When the button is clicked just grab that path and send it to print to a whatever network printer is set up?

If you guys could give a hint or a pointer where to look at that would be awesome and appreciated a lot!

Thanks,

Alex

Hi Alex,

This is almost exactly what the code I posted does. As we don’t want to print every attachment that may be present in the job, we use the document type only as a filter. So its not mandatory to make this work and these checks could be removed from the code.

For direct printing, there is probably a way to do this, maybe others more knowledgeable than me in programming could help you find a way to do that.

Christian

Hi guys, here is what I have achieved so far by adopting code for E10. I am breaking my case into the small parts and trying to implement them step by step but getting this error:

"**Error: CS1501 - line 127 (254) - No overload for method 'GetRows' takes 27 arguments**" 

for this part of code:

for(int x=0; x < edvJobList.dataView.Table.Rows.Count; x++)
{		
   JobEntryDataSet jobEntryDS = JobEntryBO.GetRows("JobNum = '" + edvJobList.dataView.Table.Rows[x] 
  ["JobNum"].ToString() + "'" ,"","","","","","","","","","","","","","","","","","","","","","","",0,1,out morePages);
}

I do understand that something wrong with arguments for GetRows methods but after numerous tries and attempts to fix it unfortunatelly I couldn’t.

If somebody knows how to fix this or what’s the problem any help would be very much appreciated.

Thank you,

Alex

Here is the code:

// **************************************************
// Custom code for JobTravForm
// Created: 4/19/2018 4:31:39 PM
// **************************************************

extern alias Erp_Adapters_JobEntry;

using System;
using System.ComponentModel;
using System.Data;
using System.Diagnostics;
using System.Windows.Forms;
using Erp.Adapters;
using Erp.UI;
using Ice.Lib;
using Ice.Adapters;
using Ice.Lib.Customization;
using Ice.Lib.ExtendedProps;
using Ice.Lib.Framework;
using Ice.Lib.Searches;
using Ice.UI.FormFunctions;
using System.IO;
using System.Collections.Generic;
using Erp.BO;
using System.Text;
using Ice.Core;
using Erp.Proxy.BO;

public class Script
{
// ** Wizard Insert Location - Do Not Remove 'Begin/End Wizard Added Module Level Variables' Comments! **
// Begin Wizard Added Module Level Variables **
	private EpiDataView edvJobList;
	private EpiDataView edvAsmList;

// End Wizard Added Module Level Variables **

// Add Custom Module Level Variables Here **
	StringBuilder Texte = new StringBuilder();

public void InitializeCustomCode()
{
	// ** Wizard Insert Location - Do not delete 'Begin/End Wizard Added Variable Initialization' lines **
	// Begin Wizard Added Variable Initialization
	edvJobList = ((EpiDataView)(this.oTrans.EpiDataViews["jobList"]));
	edvAsmList = ((EpiDataView)(this.oTrans.EpiDataViews["assemblyList"]));
	

	// End Wizard Added Variable Initialization

	// Begin Wizard Added Custom Method Calls
	this.epiButtonC1.Click += new System.EventHandler(this.epiButtonC1_Click);

	// End Wizard Added Custom Method Calls
}

public void DestroyCustomCode()
{
	// ** Wizard Insert Location - Do not delete 'Begin/End Wizard Added Object Disposal' lines **
	// Begin Wizard Added Object Disposal
	edvJobList = null;
	edvAsmList = null;
	this.epiButtonC1.Click -= new System.EventHandler(this.epiButtonC1_Click);
	Texte = null;
	// End Wizard Added Object Disposal

	// Begin Custom Code Disposal

	// End Custom Code Disposal
}

private void JobTravForm_Load(object sender, EventArgs args)
{
	// Add Event Handler Code
	
	SetVersionNumber(JobTravForm);

}

private void SetVersionNumber(EpiBaseForm form)
{
	string custName = oTrans.EpiBaseForm.CustomizationName;
	string version = "?.?";
	if ( custName.LastIndexOf("_") >= 0 )
	{
		version = custName.Substring(custName.LastIndexOf("_") + 1, custName.Length - custName.LastIndexOf("_") - 1);
	}
	form.Text = form.Text + " - Version " + version;
	
}


private void epiButtonC1_Click(object sender, System.EventArgs args)
{
	// ** Place Event Handling Code Here **

	if(edvJobList.dataView.Table.Rows.Count > 0)
	{

		Ice.Core.Session epiSession = default(Ice.Core.Session);
	   epiSession = (Ice.Core.Session)JobTravForm.Session;

		bool morePages = false;
		JobEntryAdapter JobEntryBO = new JobEntryAdapter((Ice.Core.Session)oTrans.Session);
		
		//Table temporaire pour filtrer les lots
		DataTable tempTable = new DataTable();
		tempTable.Columns.Add("JobNum", typeof(string));
		tempTable.Columns.Add("PartNum",typeof(string));
		tempTable.Columns.Add("FileName",typeof(string));
		tempTable.Columns.Add("AsmSeq", typeof(string));
		tempTable.Columns.Add("ParentPart", typeof(string));
		
		foreach (var value in tempTable.Columns){
			MessageBox.Show(value.ToString());
     	}
		for(int x=0; x < edvJobList.dataView.Table.Rows.Count; x++){
		
			JobEntryDataSet jobEntryDS = JobEntryBO.GetRows("JobNum = '" + edvJobList.dataView.Table.Rows[x]["JobNum"].ToString() + "'" ,"","","","","","","","","","","","","","","","","","","","","","","",0,1,out morePages);
		}

	}

	else
	{
		MessageBox.Show("Test");
	}

}	
}

Hi Alex,

I compared your line of code side by side with mine and it is exactly the same. Have you verified the jobnum you get as a parameter ? I would probably create a string variable and a message box just before the getRows call, to get the jobnum like this:

string jobNum = edvJobList.dataView.Table.Rows[x][“JobNum”].ToString();
MessageBox.Show(jobNum);

Or you can use visual studio in debugging mode also.

I see your code is for E10, I don’t know if there is differences in the implementation. I haven’t started to work code for E10 yet, but I have it installed for testing. I used the Business Logic Tester (great tool) to quickly verify the arguments. Seems to be the same as I what have in 9.05…

Sorry If i’m am not of much help on this one, but again I am not a developer, just an admin who loves playing with code.

The easiest and cheapest solution is to display the attachments into the job traveler itself. there is a way to automatically pull the drawings from the BOM onto the job when the job is confirmed. then using the xfileattach table, you can pull in the drawings using an OEL object in crystal using the path that is stored in that table. This is how we do it.

Hi Christian,

Thanks for your response. I have verified jobnum like you proposed and I am getting a correct jobnum which I selected as well as other parameters like PartNum. I am about to use Visual Studio to debug also.

Now I am thinking about a way to access Ice.XFileRef table which contains XFileName Column with a path (i.e. N:\Drawing Files\12in mini\M0161 headstock.dft). Then, I want to check if any of those columns Contain a part number and if it returns true, I want to pass that path to a network printer.

Let me check out what is Business Logic Tester as see this name the first time.

I appreciate any help and no matter how big it is. We all here to share experience and help each other as much as we can!

Thanks,

Alex

Hi Jeff,

We are not using Crystal report, only SSRS and as far as I explored it’s not possible to pull a drawing by a custom expression in SSRS.

Actually, Ice.XFileRef table in my case is what I need but now I am researching if there is a way to access it through a customization. Do you know any ways to achieve this?

Thanks,

Alex