4

In my Notes Database, I perform an audit when the document is saved. Pretty easy in LotusScript. I grab the original document (oDoc) from the server, then in the document I modified (mDoc), I do a Forall loop that gets the names of each item; forall item in mDoc.items. Grab the same item from oDoc, execute a function with the new item as an argument that will run down a case statement that will see if its a field we care about. if so, I update a set of list values in the document with "When", "Who", "What field", and the "New Value".

I'm doing this in a server side script. In trying this, I discovered a couple of interesting things;

currentDocument is the NotesXSPDocument that contains everything that was just changed.

currentDocument.getDocument() contains the pre-change values. It also returns a NotesDocument which has the "items" field that I can run through.

Thing is, I need something similar in the NotesXSPDocument. Is there a way in an iterative loop to grab the names and values of all items from there?

Here's the broken code. (Currently it's walking through the NotesDocument items, but those are the old values. I'd rather walk down the XSP document items)

function FInvoice_beginAudit() {
  var original_doc:NotesDocument = currentDocument.getDocument();
  var oItem:NotesItem;

  var oItems:java.util.Vector = original_doc.getItems();
  var iterator = oItems.iterator();
  while (iterator.hasNext()) {
    var oItem:NotesItem = iterator.next();
    item = currentDocument.getItemValue(oItem.getName());
    if (oItem == undefined) {
      var MasterItem =  ScreenAudit(doc,item,True)
      if (MasterItem) { return true }
      } else {
      if (item.getValueString() != oItem.getValueString()) {
        var MasterItem =  ScreenAudit(doc,Item,True);
          if (MasterItem) { return true }
      }
    }
  }
}
cjames728
  • 193
  • 1
  • 12
  • 2
    Did you try `getChangedFields()` for NotesXSPDocument? Look here for usage http://public.dhe.ibm.com/software/dw/lotus/Domino-Designer/JavaDocs/XPagesExtAPI/8.5.2/com/ibm/xsp/model/domino/wrapped/DominoDocument.html#getChangedFields() – Knut Herrmann Apr 28 '14 at 15:32
  • Knut, thanks for that one. Didn't know about it! – Patrick Sawyer Apr 28 '14 at 16:56
  • Can't seem to get that one to work; Error calling method 'getChangedFields()' on an object of type 'NotesXspDocument [Static Java Wrapper, com.ibm.xsp.model.domino.wrapped.DominoDocument]' at [xPages_SSJS.jss].FBAudit() at [xPages_SSJS.jss].saveDocument() 123: } 124: function FBAudit() { -> 125: var cFields = currentDocument.getChangedFields(); 126: print (cFields); 127: } – cjames728 Apr 28 '14 at 17:25
  • Couldn't get to work `getChangedFields()` neither but found the solution with `currentDocument.getDocument(true)` - see my answer. – Knut Herrmann Apr 28 '14 at 18:27

1 Answers1

7

You can get both versions of a document after submit - the original and the one with changed/new values:

original: var original_doc:NotesDocument = currentDocument.getDocument();

changed: var changed_doc:NotesDocument = currentDocument.getDocument(true);

This way you can compare the items for changes.

But, there is a pitfall: after assigning "changed_doc" to currentDocument.getDocument(true) the "original_doc" has the changed values too because both variables point to the same document. That's why we have to copy all items from currentDocument.getDocument() to a new temporary document first and only after get the changed values with currentDocument.getDocument(true). As an alternative you could read the original document from server like you do in LotusScript.

This is a code for detecting changed items as a starting point:

  var original_doc:NotesDocument = database.createDocument();
  currentDocument.getDocument().copyAllItems(original_doc, true);
  var changed_doc:NotesDocument = currentDocument.getDocument(true);
  var oItems:java.util.Vector = original_doc.getItems();
  var iterator = oItems.iterator();
  while (iterator.hasNext()) {
    var oItem:NotesItem = iterator.next();
    var itemName = oItem.getName();
    var cItem:NotesItem = changed_doc.getFirstItem(itemName);
    if (cItem.getText() !== oItem.getText()) {
        print("changed: " + itemName);
    }
    oItem.recycle();
    cItem.recycle();
  }
  original_doc.remove(true);
  original_doc.recycle();
Knut Herrmann
  • 30,880
  • 4
  • 31
  • 67
  • True, but when you do the second statenent, the values in original_doc assume the values in updated_doc. At least before the second statement, I do a original_doc.getFirstItem, then print the item.getText. It brings back the original value. I paste the same commands after updated_doc and it returns the new value, from the original_doc item..... most frustrating. Some kind of inheritance going on here. – cjames728 Apr 28 '14 at 19:27
  • Yes, that's what I discovered too and updated answer with a workaround :) – Knut Herrmann Apr 28 '14 at 19:35