I am deploying an articles from one org to another using java and Partner WSDL.
If one of the following fields: IsVisibleInPkb, IsVisibleInCsp, IsVisibleInPrm are set in the new article I get the following error, relative to the field name for example - for IsVisibleInPkb I get the following error:
Visible In Public Knowledge Base: value not of required type: true
It's apply to 'false' as well, and of-course the new article isn't created in the new org.
Notes: 1. Those fields are createable (I'm checking this with isCreateable when taking all the fields with describeSObject and getFields). 2. The metadata is the same in both orgs.
I can of-course not including those fields when inserting new articles, and when doing so that works, but then I need to somehow updates all those articles to match those fields state from the original org, using update (to update thos is... fields) on the newly created articles produce the same error.
Here is a sample code only to produce the error (note that I'm using some methods that I will not provide, but it pretty strait forward to understand what the code does):
Connection connProduction = new Connection();
connProduction.login("org1_user_name", "pass1");
Connection connSandBox = new Connection(Connection.CONNECTION_TYPE.Sandbox);
connSandBox.login("org2_user_name", "pass2");
String articleType = "FAQ__kav";
//Get fields of articleType:
Field[] lstArticlesFields = MetaData.getFields(connProduction, articleType);
//Build fields for org1 query:
StringBuilder sb = new StringBuilder();
sb.append(lstArticlesFields[0].getName());
for (int i = 1; i < lstArticlesFields.length; ++i)
{
if (lstArticlesFields[i].getType() == FieldType.base64)
{
continue;
}
if (lstArticlesFields[i].getType() != FieldType.id && !lstArticlesFields[i].isCreateable())
{
continue;
}
System.out.println(lstArticlesFields[i].getName());
sb.append(",");
sb.append(lstArticlesFields[i].getName());
}
String productionQuery = "SELECT " + sb.toString() + " FROM " + articleType + " WHERE Language = 'fr' AND PublishStatus = 'Online' AND KnowledgeArticleId = 'kA0b0000000L04p'";
System.out.println("productionQuery: " + productionQuery);
//Query on org1:
SObject[] articlesProduction = connProduction.getPartner().query(productionQuery);
//Build new articles for org2:
SObject[] articlesToInstertSandbox = new SObject[articlesProduction.length];
for (int i = 0; i < articlesProduction.length; ++i)
{
SObject newSO = new SObject();
newSO.setType(articleType);
for (Field f : lstArticlesFields)
{
System.out.println(f.getName() + "::" + articlesProduction[i].getField(f.getName()));
//Bypass id field:
if ("Id".equals(f.getName()))
{
continue;
}
//Bypass boolean fields to avoid IsVisibleInPkb, IsVisibleInCsp, IsVisibleInPrm fields:
if (f.getType() == FieldType._boolean)
{
continue;
}
newSO.setField(f.getName(), articlesProduction[i].getField(f.getName()));
}
articlesToInstertSandbox[i] = newSO;
}
//Create article in org2:
HashMap<Integer, String> mapIndexByIds = connSandBox.getPartner().create(articlesToInstertSandbox);
//Build fields for org2 query:
sb = new StringBuilder();
sb.append(lstArticlesFields[0].getName());
for (int i = 1; i < lstArticlesFields.length; ++i)
{
if (lstArticlesFields[i].getType() == FieldType.id)
{
continue;
}
sb.append(",");
sb.append(lstArticlesFields[i].getName());
}
String sandboxQuery = "SELECT " + sb.toString() + " FROM " + articleType + " WHERE Language = 'fr' AND PublishStatus = 'Draft' AND Id = '" + mapIndexByIds.get(0) + "'";
System.out.println("sandboxQuery: " + sandboxQuery);
//Query on org2:
SObject[] articlesSandboxDraft = connSandBox.getPartner().query(sandboxQuery);
//Update org2 article with org1 data for the boolean fields:
String id = null;
for (int i = 0; i < articlesSandboxDraft.length; ++i)
{
int fieldInd = 0;
for (Field f : lstArticlesFields)
{
System.out.println((fieldInd++) + "::");
if (f.getType() == FieldType.id)
{
//Get Id to update:
id = articlesSandboxDraft[i].getId();
//Remove id field, because when query an sobject it retrieved with two id fields
//(probably some salesforce bug), so when trying to update I get an error about duplicate Id fields!
articlesSandboxDraft[i].removeField(f.getName());
}
System.out.println("BEFORE: " + f.getName() + "::" + articlesProduction[i].getField(f.getName()));
if (f.getType() == FieldType._boolean)
{
//Update org2 article with org1 data for the boolean fields:
articlesSandboxDraft[i].setField(f.getName(), articlesProduction[i].getField(f.getName()));
}
System.out.println("AFTER: " + f.getName() + "::" + articlesSandboxDraft[i].getField(f.getName()));
}
}
//Set Id again (now it will only be one Id field as it should):
articlesSandboxDraft[0].setField("Id", id);
SaveResult[] results = connSandBox.getPartner().getPartner().update(articlesSandboxDraft);
for (int j = 0; j < results.length; j++)
{
if (results[j].isSuccess())
{
System.out.println("\nA new record was created with an ID of: " + results[j].getId());
}
else
{
for (com.sforce.soap.partner.Error error : results[j].getErrors())
{
com.sforce.soap.partner.Error err = error;
System.out.println("Errors were found on item " + j);
System.out.println("Error code: " + err.getStatusCode().toString());
System.out.println("Error message: " + err.getMessage());
}
}
}