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

Community Tip - You can subscribe to a forum, label or individual post and receive email notifications when someone posts a new topic or reply. Learn more! X

Translate the entire conversation x

How to create Custom REST END Point to create Options and Variants and assign it to a specific Part

AKC
13-Aquamarine
13-Aquamarine

How to create Custom REST END Point to create Options and Variants and assign it to a specific Part

I am exploring the feasibility of developing a unified REST endpoint that enables the creation of Options and Choices, associates an Option Set with a Product under an Option Pool, and assigns it to a specific configurable WTPart. This endpoint would also facilitate the creation of a Variant Specification. While these actions are currently performed through multiple steps in the Windchill UI, my goal is to streamline the process into a single interface. This would allow users from non-Windchill platforms to access a Product and its associated WTPart, input specific Options and Choices, and generate a Variant BOM accordingly. I seek expert guidance on the feasibility and potential challenges of implementing this approach.

2 REPLIES 2
HelesicPetr
22-Sapphire II
(To:AKC)

Hi @AKC 

Here is an example how to create own custom rest api method.

 

in the java class you just have to write a code that do what you need. This example shows just update Primary Conent Of a Document by rest api

 

1. ptc\Windchill_12.0\Windchill\codebase\rest\custom\domain\DocMgmt\v5\import.js
function action_updatePrimaryConentOfDocument(data, params) {
    var doc = Java.type('ext.sconce.solution.ODataHelper');
    return doc.updatePrimaryConentOfDocument(data, params);
}
 
2. ptc\Windchill_12.0\Windchill\codebase\rest\custom\domain\DocMgmt\v5\import.json
"actions" : [
         {
            "name": "updatePrimaryConentOfDocument",
            "importName": "updatePrimaryConentOfDocument",
            "description": "API to update update Primary Content Of WTDocument & remove existing content",
            "includeInServiceDocument": true,
            "parameters": [
                {
                    "name": "Number",
                    "type": "String",
"isNullable": false,
"isCollection": false
},
{
                    "name": "fileLocation",
                    "type": "String",
"isNullable": false,
"isCollection": false
},
{
                    "name": "fileName",
                    "type": "String",
"isNullable": false,
"isCollection": false
}
            ],
            "returnType": {
                "type": "Edm.String",
                "isCollection":false,
"isNullable": true
            }
        }
]
Input:
fileLocation: D:\TestUploadFolder
Number      : 0000001112
fileName    : fileExample.pdf
 
3. Java file:
package ext.sconce.solution;

import java.beans.PropertyVetoException;
import java.io.File;
import java.io.FileInputStream;
import java.io.IOException;
import java.util.HashMap;
import java.util.Map;

import org.apache.logging.log4j.Logger;
import org.apache.olingo.commons.api.data.Parameter;
import org.apache.olingo.commons.api.http.HttpStatusCode;
import org.apache.olingo.server.api.ODataApplicationException;
import org.json.JSONObject;

import com.flexnet.lm.binary.StringUtil;
import com.ptc.odata.core.entity.action.ActionProcessorData;
import com.ptc.odata.core.entity.property.EntityAttribute;
import com.ptc.odata.core.entity.property.PropertyValueType;

import wt.content.ApplicationData;
import wt.content.ContentHelper;
import wt.content.ContentHolder;
import wt.content.ContentItem;
import wt.content.ContentRoleType;
import wt.content.ContentServerHelper;
import wt.doc.WTDocument;
import wt.fc.QueryResult;
import wt.log4j.LogR;
import wt.pds.StatementSpec;
import wt.pom.Transaction;
import wt.util.WTException;
import wt.util.WTProperties;
import wt.util.WTPropertyVetoException;

public class ODataHelper {

private static String CLASSNAME = ODataHelper.class.getName();
private static Logger logger = LogR.getLoggerInternal(CLASSNAME);

public static EntityAttribute updatePrimaryConentOfDocument(ActionProcessorData data,
HashMap<String, Parameter> params) {
if (logger.isDebugEnabled())
logger.debug(CLASSNAME + " - updatePrimaryConentOfDocument Start");

Map<String, Object> responseMap = new HashMap<String, Object>();
String fileName = "";
String Number = "";
String fileLocation = "";
try {
Number = getStringParameter(data, params, "Number");
fileLocation = getStringParameter(data, params, "fileLocation");
fileName = getStringParameter(data, params, "fileName");
logger.debug("Number:" + Number + "fileLocation" + fileLocation + "fileName " + fileName);
updatePrimaryConentOfDocument(Number, fileLocation, fileName);
responseMap.put("Message", "update Primary Conent Of Document successfully.");
} catch (ODataApplicationException e) {
e.printStackTrace();
responseMap.put("Error", e.getMessage());
}
EntityAttribute result = new EntityAttribute(null, "values", PropertyValueType.PRIMITIVE,
new JSONObject(responseMap));

return result;
}

public static String getStringParameter(ActionProcessorData data, Map params, String stringName)
throws ODataApplicationException {
StringUtil.isEmpty("");
Parameter param = (Parameter) params.get(stringName);
if (org.springframework.util.StringUtils.isEmpty(param.getValue())) {
String errorMsg = "Invalid Parameter - " + stringName + "not found in the request";
throw new ODataApplicationException(errorMsg, HttpStatusCode.BAD_REQUEST.getStatusCode(), data.getLocale());
} else {
return (String) param.getValue();
}
}

public static void updatePrimaryConentOfDocument(String Number, String fileLocation, String fileName) {
logger.debug("updatePrimaryConentOfDocument - replaceContent - BEGIN");
WTDocument wtdoc = getDocumentByNumber(Number);
if (wtdoc != null) {
Transaction trx = new Transaction();
try {
trx.start();
ApplicationData wtdContent = ApplicationData.newApplicationData((ContentHolder) wtdoc);
wtdContent.setFileName(fileName);
wtdContent.setRole(ContentRoleType.PRIMARY);

WTProperties wtproperties = wt.util.WTProperties.getLocalProperties();
String dirSeparator = wtproperties.getProperty("dir.sep");
logger.debug("Path : " + fileLocation + dirSeparator + fileName);
File file = new File(fileLocation + dirSeparator + fileName);

wtdoc = (WTDocument) wt.vc.VersionControlHelper.service.getLatestIteration(wtdoc, true);
deletePrimaryContent(wtdoc);
try (FileInputStream istream = new FileInputStream(file)) {
ContentServerHelper.service.updatePrimary(wtdoc, wtdContent, istream);
istream.close();
}

ContentServerHelper.service.updateHolderFormat(wtdoc);
logger.debug("Replaced content - wtdoc: " + wtdoc.getIdentity());
trx.commit();
trx = null;
logger.debug("Completed updatePrimaryConentOfDocument END");
} catch (WTException | PropertyVetoException | IOException ex) {
System.out.println(
" Error while updating primary content = " + ex + "for WTDocument " + wtdoc.getIdentity());
ex.printStackTrace();
} finally {
if (trx != null) {
trx.rollback();
}
}
}
}

public static WTDocument deletePrimaryContent(WTDocument wtdoc) {
try {
QueryResult qrCI = ContentHelper.service.getContentsByRole((ContentHolder) wtdoc, ContentRoleType.PRIMARY);
if (qrCI.size() > 0) {
ContentItem ci = (ContentItem) qrCI.nextElement();
ContentServerHelper.service.deleteContent(wtdoc, ci);
}
} catch (WTException | WTPropertyVetoException ex) {
ex.printStackTrace();
}
return wtdoc;
}

public static WTDocument getDocumentByNumber(String docNumber) {
WTDocument doc = null;
try {
wt.fc.QueryResult result = null;
wt.query.QuerySpec query = new wt.query.QuerySpec(WTDocument.class);
wt.query.WhereExpression condition1 = new wt.query.SearchCondition(WTDocument.class, WTDocument.NUMBER,
wt.query.SearchCondition.EQUAL, docNumber);
int fromIndices[] = { 0, 1 };
query.appendWhere(condition1, fromIndices);
result = wt.fc.PersistenceHelper.manager.find((StatementSpec) query);
while (result.hasMoreElements()) {
doc = (WTDocument) result.nextElement();
}
} catch (Exception e) {
e.printStackTrace();
}
return doc;
}
}
 
hope this can help how to create own RestApi function.
 
PetrH
AKC
13-Aquamarine
13-Aquamarine
(To:HelesicPetr)

Hello Petr,

 

Thank you for your time and valuable response. While I am familiar with developing custom REST endpoints, I am specifically seeking guidance related to Options and Variants. For instance, I am trying to assign an Option Set to a Configurable Part, but I have not been able to find any relevant API for this purpose. Any assistance in this regard would be greatly appreciated

 

 

Announcements
Top Tags