Showing results for 
Search instead for 
Did you mean: 
Showing results for 
Search instead for 
Did you mean: 

ESI Target architecture


ESI Target architecture

We are in the process of implementing ESI for Oracle. Currently we are doing some unit testing and finding significant issues with the OOTB functionality. I'm starting to question the way we have configured our Distribution Targets and wanted to see if others using ESI have setup their Distributions in a similar manner. If you haven't, how are you handled assignment of Distribution Targets?
One for the requirements our team had was to have Windchill automatically assign Distribution Targets depending on the Product/Library that a Part lives in. What this has led to is there are multiple Distribution Targets pointing to the same Oracle inventory org (the SAP equivalent may be named differently).
· Product 1
o OR1-Product 1 : Oracle Org = OR1, It's Active, It's a Default Target
o OR2-Product 1 : Oracle Org = OR2, It's Active
o OR3-Product 1 : Oracle Org = OR3, It's Active
· Product 2
o OR1-Product 2 : Oracle Org = OR1, It's Active
o OR2-Product 2 : Oracle Org = OR2, It's Active, It's a Default Target
o OR3-Product 3 : Oracle Org = OR3, It's Active
· Product 3
o OR1-Product 3 : Oracle Org = OR1, It's Active
o OR2-Product 3 : Oracle Org = OR2, It's Active
o OR3-Product 3 : Oracle Org = OR3, It's Active, It's a Default Target

What I’m starting to rethink is would it be easier to have at the Site or Org level three Targets

  • OR1
  • OR2
  • OR3
Then have some mapping file that specifies for a given Context, the default Distribution Target(s) for that Context.
I’d be interested to hear what others are doing for their setups.

ESI Target architecture

We use Baan as our ERP system.

We have two Baan Logistics Companies, one for new production, and one for

Each logistics company has its own has a corresponding distribution target
in PDMLink: one for new production, and one for aftermarket.

We also use the view version feature in Windchill to allow a Manufacturing
Process view of a BOM to differ from the Engineering view of a BOM.
However, we encourage the use of a single BOM as much as possible, so we
allow the Engineering BOM to RTP to Baan if it double as the Manufacturing
Process view. That is why we call the initial view a "Common" view, and
it's child view the "Manufacturing Process" view. As an interesting note,
the out of the box RTP creation of XML appears to use the latest
configuraiton specification of the parent part version rather than a
variable or system-wide configuration specification. For example, a
Common view version will send the child versions using the latest Common
config spec, while a Manufacturing Proccess view version will send the
child versions using the latest Manufacturing Process config spec. This
subtle point is important when auto-assigning ESITargets to child part

We have a large number of site-specific business logic that has to make
sure a BOM version is perfectly correct before we RTP to Baan using the
ESI tools that PTC provides to generate XML that we send to Baan via our
own implementation of a WPS middleware solution.

The pre-checks are conducted in a workflow and have 4 phases - all prior
to using PTC's XML generation for processing to Baan.

First, we do multiple business logic checks. For example, if a "standard"
part has "nonstandard" or "development" children, then it is flagged as an
error and kicked back to the person conducting the RTP on a workflow task.

Second, we assign ESI targets to the parent and all children to ensure
that the BOM is properly set up with all correct target assignments. Doing
this ESI target assignment manually is just too much work on a large BOM,
and too prone to user error. So, we automate it.

Third, we assign one and only one user to a role on the part being RTP'ed
("Manufacturing Engineer") to put in our XML sent to Baan as the "user"
id. We have logic that gets that user ID. We cannot use "last modified
by" because we sometimes have to check out the part as an administrator to
assign line numbers, below.

Lastly, we check for line numbers on all child parts. If all child parts
do not have a line number, then the program checks out the part and
assigns line numbers those children.

If you have a specific question on how we do any of this, I'd be happy to
post that part of the code.

From a process perspective, it is worth noting that we were not able to
use the change process for direct RTP to our ERP system. Instead, we give
a choice of two approaches. First, if a completed change (through a
change transition in the part lifecycle) or a user via "set state" causes
a part version to go to "Under Review," then we kick off a workflow in
which that user gets a worklist task to "Assign the Manufacturing
Engineer." That task also lists any preprocessing errors that need to be
fixed prior to RTP. Second, a user can use a promotion to send more than
one part version over to the same distribution target at one time. In the
case of a promotion, we error check all the attached target part versions,
and if there are no errors, then we kick off an individual RTP process for
each target version that then RTPs that version as if it were kicked off

Lastly, as an aid to RTP error and success message posting, the RTP
workflow, after synchronizing on the RTP event and after capturing the
event as Success or Failure, puts a hyperlink in an e-mail to the RTP'ing
users directly to the RTP status for that version. This is really useful,
so I'll include the code here.

//Create links to RTP status to embed in success or failure messages.
// I have two urls - one for each ESI target. This is a bit extra since
both actually go to the same place when there are two targets,
// but that is how it looks on the OOTB status page (one link for each
target), so I replicated that in the e-mail.
// This is in the RTP workflow for each part version being RTPed. I hard
coded it for no more than 2 ESI targets only because that is all we have
right now.
// url_1 and url_2 are just worfkow process-level String variables.

wt.part.WTPart part = (wt.part.WTPart)primaryBusinessObject;
int count = 1;
url_1 = ";
url_2 = ";
try {
java.util.Collection targetAssoc =
java.util.Iterator targets = targetAssoc.iterator();
while (targets.hasNext()) {
com.ptc.windchill.esi.tgt.ESITargetAssociation eta =
com.ptc.windchill.esi.tgt.ESITarget esiTarget =
if (count == 1) {
url_1 = ""/netmarkets/jsp/esiTransaction/relatedTransactions.jsp?oid=OR%3A" +
part.toString() + "&portlet=pop...

} catch (com.ptc.windchill.esi.tgt.ESINoTargetAssignmentException
ignoreThisExceptionAndKeepProcessing) {"SolarRTP status link: No
ESI Targets");
} catch (Exception ex) {"SolarRTP status link:
Error ex = " + ex.toString());


Next, in the same workflow, I call out the links to either the success or
failure in a workflow e-mail robot that calls out the variable URLs in the
e-mail robot Message area like this.