The wrapper classes I blogged about in February went down a lot better than I thought they might.
So, taking it further. Let's extend the DocumentWrapper class some more. Since first writing about them on here I've been busy using and extending them as I go. Here are a few examples of some of the properties I've added
Simple Helper Properties
Some very simple properties: WebLink, UNID and IsNew.
Property Get WebLink As String WebLink = "/" + Replace(web.database.Filepath, "\", "/") + "/0/" + UNID + "?OpenDocument" End Property Property Get UNID As String UNID = Document.Universalid End Property Property Get IsNew As Boolean IsNew = document.Isnewnote End Property
These don't do anything that can't already be done. They just make it simpler and quicker to code.
Logging Document Actions
Properties are all well and good. But they're just borne of laziness really. Let's add a method or two, to make it really useful. How about adding a new method to the base class called LogAction() which you might use like this:
And the method might look like this (it assumes all your Forms have a standard field called "ActionLog"):
Sub LogAction( Action As String ) Dim item as NotesItem Set item = document.GetFirstItem( "ActionLog" ) Call item.AppendToTextList( Action + " on " + Format(Now, "dd mmm yy") +_ " at " + Format(Now, "hh:nn:ss") + " by " + web.User.Abbreviated ) End Sub
The web.user part assumes you're already using my WebSession Class.
If you never actually delete documents, but merely flag them as deleted then you can give all objects based on the DocumentWrapper class a Delete() method, like so:
Sub MarkDeleted() Call SetFieldValue("Delete", "1") Call LogAction("Document Deleted") End Sub
You can then add an IsDeleted property to the DocumentWrapper class, like so:
Property IsDeleted As Boolean IsDeleted = (GetFieldValue("Deleted")="1") End If
At this point you might consider moving some of the field name and their values to "static strings" at the top of the class, then changes the corresponding methods, like this:
Const DELETED_FIELD_NAME = "Deleted" Const DELETED_FIELD_VALUE = "1" Sub MarkDeleted() Call SetFieldValue(DELETED_FIELD_NAME, DELETED_FIELD_VALUE) End Sub Property IsDeleted As Boolean IsDeleted = (GetFieldValue(DELETED_FIELD_NAME) = DELETED_FIELD_VALUE) End If
Naturally you might want to add an UnDelete() method too...
Extending Derived Classes
So far I've talked about extending the base DocumentWrapper class. Everything we add there is available to all classes derived from it. But, obviously, you can also add properties and methods to the derived classes. For example, the Invoice class might want an Approve() method. This could either simply flag it as approved or perform some more complex workflow logic, passing it between approvers.
Class Invoice As DocumentWrapper Sub Approve() 'Do whatever LogAction("Approved") End Sub Sub AddItem(Description as String, Value as Currency) 'Add to the relevant fields End Sub End Class
Notice I added a call to LogAction() inside the Approve() method. That way you never forget to log the approval no matter where you call the Approve() method from.
The possibilities are almost endless.
These wrapper classes have completely changed the way I code my Domino web apps! My dream has always been to be a "proper coder". I'd love to be able to work completely in Visual Studio writing C#. Unless you've done that you won't appreciate what a pleasure it can be. I get a buzz from writing my own classes and then using them. This is a buzz I've never really had while coding for Domino. Until now. These wrapper classes will have to do for the time being.
Next week I'll talk even more about them and show how to handle collections of documents that belong to other documents. While I go, I'm working on a demo app that brings it all together.