Relating Articles with Knowledge v3 - My fix on versioning issues
We are doing a knowledge project, rebuilding our knowledge base to use the Knowledge Portal instead of the old UI pages. I don't know who this is for but I hope it helps.
As part of this we have been looking to leverage relational data, Linked Articles, Affected Products, Models and adding a Location Field that displays in the portal page.
The problem we came across was that you could relate articles but with versioning turned on this broke the relationship. When you checked out an article the child articles would go to the new version but anything that related to the old one were stuck pointing to an older revision. Another issue that when you related an article you must select from Published versions and if the article had a checked out version as soon at it made it to the Published state the linked article didn't come across because it was not superseded.
To fix this I have done the following:
- Created a business rule on the KB_2_KB Table:Insert - Related Versioning Support
(function executeRule(current, previous /*null when async*/) { // If the inserted related article is not the latest. Add it's latest //gs.log("Related Versioning Support - Start Business Rule"); if(current.related_kb_knowledge.latest == false){ //gs.log("Related Versioning Support - This is not the latest"); var gr = new GlideRecord('kb_knowledge'); //Latest version gr.addQuery('latest', 'true'); //Match on the current child article_id gr.addQuery('article_id', current.related_kb_knowledge.article_id); gr.query(); //gs.log("Related Versioning Support - Searching for the latest"); if (gr.next()){ //Also add this draft version //gs.log("Related Versioning Support - Create reference to the latest"); var newgr = new GlideRecord('kb_2_kb'); newgr.initialize(); //the current parent newgr.setValue('kb_knowledge',current.kb_knowledge.sys_id); newgr.setValue('related_kb_knowledge',gr.sys_id); newgr.setValue('active','false'); //don't make active just yet. It will break the portal newgr.setValue('order',current.order); newgr.insert(); //gs.log("Related Versioning Support - Latest Added"); } } //gs.log("Related Versioning Support - Finished"); })(current, previous); Created and override of the _copyRelatedArticles in the KBVersioning script include/nav_to.do?uri=sys_script_include.do?sys_id=1f4b1fe4db122200a042f278f0b8f5a7
```
var KBVersioning = Class.create();
KBVersioning.prototype = Object.extendsObject(KBVersioningSNC, {/**
* OVERIDE Copy Related Articles to new version
*
*
* @param String oldSysId
* @param String newSysId
*
**/
_copyRelatedArticles: function(oldSysId,current){
//OOB gets any active child articles and add them to the new version
var gr = new GlideRecord('kb_2_kb');
gr.addQuery('active', 'true');
gr.addQuery('kb_knowledge', oldSysId);
gr.query();
while (gr.next()){
var newgr = new GlideRecord('kb_2_kb');
newgr.initialize();
newgr.setValue('kb_knowledge',current.getUniqueValue());
newgr.setValue('related_kb_knowledge',gr.related_kb_knowledge);
newgr.setValue('active','true');
newgr.setValue('order',gr.order);
newgr.insert();
}
//Take the active m2m links. Previouslly if a article had a link to parent it was dropped on Checkout. The link to the child would be stuck on a previous version.
var grParent = new GlideRecord('kb_2_kb');
//grParent.addQuery('active', 'true'); // I don't think this matters anymore
grParent.addQuery('related_kb_knowledge', oldSysId); //Change to look for references to the old article from kb_knowledge
grParent.query();
while (grParent.next()){
var newgrParent = new GlideRecord('kb_2_kb');
newgrParent.initialize();
newgrParent.setValue('kb_knowledge', grParent.kb_knowledge.sys_id);
newgrParent.setValue('related_kb_knowledge',current.getUniqueValue());
newgrParent.setValue('active','false'); //don't make it active yet or it breaks with kb portal Related Articles widget. This will be made Active if published in the buisiness rule
newgrParent.setValue('order',grParent.order);
newgrParent.insert();
}},
type: 'KBVersioning'
});
```Finally complete a clean up of the previous versions when an article Workflow changes to Published and is the latest on the kb_knowledge table
(function executeRule(current, previous /*null when async*/ ) {
//Get the kb m2m table where there is a reference to this article version as the child related_kb_knowledge
var grParent = new GlideRecord('kb_2_kb');
grParent.addQuery('related_kb_knowledge', current.sys_id); //Change to look for references to this article so we can pivot from the parent for old versions
grParent.query();
//gs.log('Related Article Versioning BR: Get all parents');
while (grParent.next()) {
//gs.log('Related Article Versioning BR: - Got one: ' + grParent.getDisplayValue('kb_knowledge'));
var checkAllRefferences = new GlideRecord('kb_2_kb');
checkAllRefferences.addQuery('active', 'true');
checkAllRefferences.addQuery('kb_knowledge', grParent.kb_knowledge); //From the current grParent lets pivot
checkAllRefferences.addQuery('related_kb_knowledge', '!=', current.sys_id);
checkAllRefferences.query();
//gs.log('Related Article Versioning BR: - Pivoting: ' + grParent.getDisplayValue('kb_knowledge'));
//Loop the parent articles
while (checkAllRefferences.next()) {
//gs.log('Related Article Versioning BR: - Pivoting: ' + grParent.getDisplayValue('kb_knowledge') + ' Inspecting : ' + checkAllRefferences.getDisplayValue('related_kb_knowledge'));
if (checkAllRefferences.related_kb_knowledge.article_id == current.article_id && checkAllRefferences.latest != true) {
//This is why we're here, this is the same article but a previous version
//gs.log('Related Article Versioning BR: - Pivoting: ' + grParent.getDisplayValue('kb_knowledge') + ' Deleting : ' + checkAllRefferences.getDisplayValue('related_kb_knowledge') + ' this article was replaced by : ' + current.getDisplayValue());
//Do make inactive or just delete it
checkAllRefferences.deleteRecord();
} else {
//gs.log('Related Article Versioning BR: - Pivoting: ' + grParent.getDisplayValue('kb_knowledge') + ' Ignore : ' + checkAllRefferences.getDisplayValue('related_kb_knowledge') + ' Its not what we want');
}
}
//Finally make this active because it's now published and may have been
if (grParent.active != true) {
grParent.active = true;
grParent.update();
}
}
})(current, previous);
Now as an example if I relate KB65 to KB66:
and then check out KB66 and publish it I get to keep the relationship and only the most recent shows in the portal:
Additionally if I Checkout KB65 and relate KB74 before I have published KB65 I will see both are addded and the minor versions not active yet:
After publishing KB65 the BR will clean up the links on the new article (I skipped a couple of versions because I forgot to make the BR trigger on update):
I hope that this can help others in the future, if we find any issues I'll be sure to update the article. Happy for any code reviews. If you have anything cool or helpful in your knowledge base leave a comment.
Labels:
https://www.servicenow.com/community/now-platform-articles/relating-articles-with-knowledge-v3-my-fix-on-versioning-issues/ta-p/2296144
