Here is the solution code that you will need:
PartReferenceLink.js
function getRelatedEntityCollection(navigationData) {
var HashMap = Java.type('java.util.HashMap');
var WTArrayList = Java.type('wt.fc.collections.WTArrayList');
var Collections = Java.type('java.util.Collections');
var VersionControlHelper = Java.type("wt.vc.VersionControlHelper");
var SessionHelper = Java.type('wt.session.SessionHelper');
var AccessControlHelper = Java.type('wt.access.AccessControlHelper');
var AccessPermission = Java.type('wt.access.AccessPermission');
var ODataApplicationException = Java.type('org.apache.olingo.server.api.ODataApplicationException');
var HttpStatusCode = Java.type('org.apache.olingo.commons.api.http.HttpStatusCode');
var WTMessage = Java.type('wt.util.WTMessage');
var AccessResource = Java.type('wt.access.accessResource');
var targetName = navigationData.getTargetSetName();
var sourceLinks = new WTArrayList(navigationData.getSourceObjects());
var user = SessionHelper.getPrincipal();
if ("References".equals(targetName)) {
var map = new HashMap();
try {
SessionHelper.manager.setAdministrator();
for (var i = 0, l = sourceLinks.size(); i < l; i++) {
var sourceLink = sourceLinks.getPersistable(i);
var document = sourceLink.getRoleBObject();
var latestDocument = VersionControlHelper.service.getLatestIteration(document, false);
var hasAccessToReferencedBy = AccessControlHelper.manager.hasAccess(user, latestDocument, AccessPermission.READ);
if (hasAccessToReferencedBy) {
map.put(sourceLink, Collections.singletonList(latestDocument));
} else {
var errorMsg = WTMessage.getLocalizedMessage(AccessResource.class.getName(),
AccessResource.SECURED_INFORMATION, null, navigationData.getLocale());
throw new ODataApplicationException(errorMsg, HttpStatusCode.FORBIDDEN.getStatusCode(),
navigationData.getLocale());
}
}
} finally {
// de-elevate administrator
SessionHelper.manager.setPrincipal(user.getName());
}
return map;
}
return new HashMap();
}
function processAdditionalAttributes(entity, object, data, processor) {
var ArrayList = Java.type('java.util.ArrayList');
var WTPart = Java.type('wt.part.WTPart');
var WTDocument = Java.type('wt.doc.WTDocument');
var NmOid = Java.type('com.ptc.netmarkets.model.NmOid');
var EntityIDUtils = Java.type('com.ptc.odata.core.entity.processor.EntityIDUtils');
var AttributeData = Java.type('com.ptc.odata.windchill.entity.processor.AttributeData');
var EntityOperation = Java.type('com.ptc.odata.core.entity.processor.EntityOperation');
var ODataApplicationException = Java.type('org.apache.olingo.server.api.ODataApplicationException');
var HttpStatusCode = Java.type('org.apache.olingo.commons.api.http.HttpStatusCode');
var WTMessage = Java.type('wt.util.WTMessage');
var ProdMgmtRB = Java.type('com.ptc.odata.windchill.part.entity.ProdMgmtRB');
var AssociationConstraintHelper = Java.type('com.ptc.core.meta.type.mgmt.server.impl.association.AssociationConstraintHelper');
var ClientTypedUtility = Java.type('wt.type.ClientTypedUtility');
var attributes = new ArrayList(2);
if (data.getOperation() == EntityOperation.CREATE) {
var referencesIdStr = EntityIDUtils.getInstance().getBindingLinkId(data, entity, "References");
var referencesOid = referencesIdStr != null ? NmOid.newNmOid(referencesIdStr) : null;
if (referencesOid != null && referencesOid.isA(WTDocument.class)) {
attributes.add(new AttributeData("references", referencesOid.getRefObject().getMaster()));
}
var referencePart = data.getSourceObjects().iterator().next();
attributes.add(new AttributeData("referencedBy", referencePart));
// make sure our objects are valid for the link constraints
if (!AssociationConstraintHelper.service.isValidAssociation(
referencePart,
ClientTypedUtility.getTypeIdentifier("wt.part.WTPartReferenceLink"),
referencesOid.getRefObject())) {
var errorMsg = "Invalid types for link, does not meet relationship constraints";
throw new ODataApplicationException(errorMsg, HttpStatusCode.FORBIDDEN.getStatusCode(), data.getLocale())
}
}
return attributes;
}
function toObjects(entities, processorData) {
var ObjectAttributeProcessor = Java.type('com.ptc.odata.windchill.entity.processor.ObjectAttributeProcessor');
var ODataApplicationException = Java.type('org.apache.olingo.server.api.ODataApplicationException');
var HttpStatusCode = Java.type('org.apache.olingo.commons.api.http.HttpStatusCode');
var WTMessage = Java.type('wt.util.WTMessage');
var ProdMgmtRB = Java.type('com.ptc.odata.windchill.part.entity.ProdMgmtRB');
// create the object the normal way
var entityToObjectMap = ObjectAttributeProcessor.newInstance().toObjects(entities, processorData);
return entityToObjectMap;
}
function checkForCheckout(newObject, createdEntity, processorData) {
var ODataApplicationException = Java.type('org.apache.olingo.server.api.ODataApplicationException');
var HttpStatusCode = Java.type('org.apache.olingo.commons.api.http.HttpStatusCode');
var WTMessage = Java.type('wt.util.WTMessage');
var ProdMgmtRB = Java.type('com.ptc.odata.windchill.part.entity.ProdMgmtRB');
var WorkInProgressHelper = Java.type('wt.vc.wip.WorkInProgressHelper');
var SessionHelper = Java.type('wt.session.SessionHelper');
var referencePart = newObject.getReferencedBy();
// check that the part is checked out and it is checked out to us
if (!WorkInProgressHelper.isCheckedOut(referencePart, SessionHelper.getPrincipal()) ||
!WorkInProgressHelper.isReservedWorkingCopy(referencePart)) {
var errorMsg = "Part must be checked out and be the working copy to add, update, or delete WTPartReferenceLink";
throw new ODataApplicationException(errorMsg, HttpStatusCode.FORBIDDEN.getStatusCode(), processorData
.getLocale())
} else {
processorData.setContinueProcessing(true);
return newObject;
}
}
function storeNewObject(objectToSave, entity, processorData) {
return checkForCheckout(objectToSave, entity, processorData);
}
function saveObject(objectToSave, entity, processorData) {
return checkForCheckout(objectToSave, entity, processorData);
}
PartReferenceLink.json
{
"name":"PartReferenceLink",
"collectionName":"PartReferenceLinks",
"type":"wcType",
"wcType":"wt.part.WTPartReferenceLink",
"description":"Part reference link",
"operations":"CREATE,UPDATE,DELETE",
"includeInServiceDocument":false,
"defaultForWcType":true,
"parent":{
"name":"WindchillEntities"
},
"attributes":[],
"inherits":[
{
"name": "softattributable",
"version": "5"
}
],
"navigations":[
{
"name":"ReferencedBy",
"target":"Parts",
"type":"Part",
"isCollection":false,
"partner":"",
"internalNameForDisplayName":"referencedBy"
},
{
"name":"References",
"target":"PTC.DocMgmt.Documents",
"type":"PTC.DocMgmt.Document",
"isCollection":false,
"partner":"",
"internalNameForDisplayName":"references"
}
]
}
Now you can hit this endpoint:
POST /ProdMgmt/Parts('{PartId}')/References
{
"ReferencedBy@odata.bind": "PTC.ProdMgmt.MyCustomPartEntity('{PartId}')",
"References@odata.bind": "PTC.DocMgmt.Documents('{DocumentId}')"
}
You can add it to your CCD package by putting the files in this big nested folder structure:
/my_CustomModule/main/resources/rest/custom/domain/ProdMgmt/v7/entity/