0

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());
        }
    }
}
  • Are you able to assign data categories to the articles upon creation? – PepeFloyd Nov 10 '14 at 22:49
  • I already answered my question. I have built a full tool on Heroku to deoloy articles from one org to another, includes data categories, images and attachments. – GoldenAxe Nov 11 '14 at 4:09
  • Thanks, I was wondering if it was possible to assign the categories upon insertion but it seems it can only be done after the articles have been inserted. – PepeFloyd Nov 11 '14 at 10:39
0

I have found the solution: The checkbox field value come from the server as Object, and the Object it's actually String, if I want to save it to another org, I need to convert it first to boolean!

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.