Retrieving PDF from XML - Transaction Point

Discussions concerning general integration topics.

Moderator: Phil Barton

Shevy
Posts: 48
Joined: Tue Dec 23, 2008 12:21 pm

Retrieving PDF from XML - Transaction Point

Post by Shevy »

My company currently has Proform Enterprise Edition 4.0. We also have an internal website where we save all the readydocs in PDF format per file. The way this is currently done is, as the users close out of the file, they click "Attach document" -> "Attach Readydoc". The documents that they choose get embedded into an XML file which is created automatically. I wrote a program to extract these pdf documents and post them to our internal website.
We are now moving to Select. Is there still an option to "attach ready docs"? Is an XML file created? Or is this done completely differently.
If anyone has any information for me on this I would greatly appreciate.
Thank you.
Mark McKenna

Re: Retrieving PDF from XML - Transaction Point

Post by Mark McKenna »

The functionality you're referring to in Enterprise is part of the Transaction Point feature, which is not yet implemented in Select. The documents that were selected by the user to be attached are encoded using the Base64 binary-to-text scheme and then embedded within an XML file for transmittal. It sounds like you were using the Transaction Point embedding feature to do the work of converting the ReadyDocs->PDF->Text, a process you then reversed in order to publish the binary PDF to some internal storage medium. Since its not implemented yet, the flow I prescribe below will be a little different.

Select offers a printing pipeline that exposes every print job to a customer's development team. This pipeline consists of any number of dispatch handlers that run sequentially. A default installation of Select offers built-in handlers that provide collating, watermarking, printing, emailing, saving to file, publishing, and auditing services. In other words, we're consumers of our own pipeline. These handlers can be removed and new handlers can be added after installation to meet the particular needs of the customer. A handler is nothing more than a class that implements a simple interface and has been registered with our system.

Every ReadyDoc that is generated for output via Printer, Email, File Save, etc. is first converted to PDF format before becoming part of the job. Then, the entire job is dropped onto the pipeline. As an outside developer, you have access to the print job and the individual items in the print job, from within your dispatch handler class. Each item in the print job exposes the location of its related PDF file. Here's a basic example of something you may want to do:

Code: Select all

class MyDispatchHandler : PrintDispatchHandler
{
    protected override bool OnHandleDispatched( IPrintJob printJob )
    {
        // rip through the individual items in the print job
        foreach ( IPrintJobItem item in printJob.Items )
        {
            // here's the PDF location 
            FileInfo fi = item.Properties["FileLocation"] as FileInfo;
            // do something with it
        }
        
        // allow the pipeline to continue
        return false;
    }
}
How you configure the handler and what kinds of print jobs it interacts with really depends on the behavior you want. For example, we offer the concept of "publishing" a ReadyDoc to essentially be an attachment to the Order. By default, we have a dispatch handler that deals with this type of print job specifically by storing the PDF on disk and saving a "link" to it with the Order. You may replace our storage mechanism with one of your choosing (e.g. your own DMS) or you may choose to replace our dispatch handler altogether and add your own that does whatever you want with the PDFs exposed by the pipeline.

Hopefully this provides a bit of insight - let me know if you have any other questions.
Shevy
Posts: 48
Joined: Tue Dec 23, 2008 12:21 pm

Re: Retrieving PDF from XML - Transaction Point

Post by Shevy »

Thank you for your response.
I am not 100% clear as to how I go about adding this handler. Where would I put that code? It sounds like I would want to somehow have the handler run on the "attach file".
Can you give me more step by step guidance?

Another question for you. There may be a different way for me to go about doing what I want to do through a word add-in. Since all the documents open in word I was thinking of writing some kind of macro in the normal.dot template. It doesnt look like select uses the full version of word, is that correct? Can I add in my add-in to this?

Thanks.
Mark McKenna

Re: Retrieving PDF from XML - Transaction Point

Post by Mark McKenna »

Select uses a component that emulates the functionality of MS Word, but it is not Word. You are currently able to export our ReadyDocs as Word binary files on a one-by-one basis but I doubt that's really what you're looking for here. The user would need to preview the documents and, one-by-one, select File->Save from the preview form. Currently this means of saving documents to file does not utilize the printing pipeline I described so any manipulation performed on that Word document would need to be initiated outside of Select. Not very smooth...

On the other hand, each of those buttons on the Documents tab (Print, Email, Publish, etc.) do result in a utilization of the pipeline, so you can "hook" any of them by providing a printing pipeline dispatch handler.

Say, hypothetically, your desired workflow would be that a user selects a set of ReadyDocs and clicks Print. At that point, you would like a dialog to appear that asks whether the destination ought to be the physical printer, or the attachment medium you've described. This would be accomplished by creating a dispatch handler that executes prior to our default Print handler - and in it you would ask the user what the intended destination is and either (a) do nothing and allow the pipeline to continue if the user chooses "Printer", or (b) do your processing of the PDF files that are already part of the print job if the user chooses "Attachment", then halt the pipeline to prevent downstream handlers from executing. That's just one example of how you might choose the leverage the pipeline. In your case it may make more sense to the user if you hooked the Publish button - optionally replacing our default handler altogether so that "Publish" comes to mean "Attach Documents" in your environment.

Pipeline dispatch handlers are created and installed as part of a "Package" that is described in the SDK, along with working sample code to get you started. Alongside the basic extension Package that you would create, you would provide a handler class similar to that which I outlined in my previous post, and then register it via the package, like this:

Code: Select all

// This attribute configures the handler to run in the main Processing stage with a priority of 25
// which would run just before our default Publish handler which has a priority of 30. All handler
// configuration, including that of our default handlers, is stored in the Registry.
[ProvidePrintDispatchHandler( typeof( MyDispatchHandler ), PipelineStage.Processing, 25 )]
class MyPackage : SoftPro.Select.Shell.Package
{
    protected override void OnInitialize( )
    {
         base.RegisterPrintDispatchHandler( new MyDispatchHandler( ) );
    }
}
Shevy
Posts: 48
Joined: Tue Dec 23, 2008 12:21 pm

Re: Retrieving PDF from XML - Transaction Point

Post by Shevy »

I like the idea that you mentioned of using the "publish button", instead of the "print button". How do I go about making that button usable?
I have been trying to get the "Simple Package" opened and have been getting the following error:

"Unable to read the project file "Simple Package.csproj" C:\Sdk\SoftPro\Select SDK\Samples\SimplePackage.csproj(3,11), The imported Project "C:\Tools\Build\SoftPro.csharp.settings.targets was not found. Confirm that the path in the <Import> declaration is correct, and that the file exists on disk.

What am I missing.
Thanks.
Mark McKenna

Re: Retrieving PDF from XML - Transaction Point

Post by Mark McKenna »

The zipped projects in the SDK are not meant to be opened directly, rather, installation of the SDK (as you've done) sets up a series of templates for you to consume. Open up Visual Studio and do File->New Project, then under Visual C# there should be a SoftPro section and, under that, a Package template you can use. It will create a new project for you using our Package template to get you started. One you have a working Package class, your next step would be to create a dispatch handler class and associate it with your new package, then register the package with Select.

As far as the Publish button goes, "publishing" is something we loosely associate with the optional SPImage product inside Select. By default, published documents become attachments to the Order by our storing of the ReadyDoc's PDF image to the directory specified under SPAdmin->Profiles->Managers & Report Preferences->SPImage Preferences, and then saving a link to that file location along with the Order when it is saved. As such, to activate the Publish button, a valid directory path must be provided. Note that while SPImage itself is pretty cool and allows you to also scan external documents and such in as attachments to the Order, you don't need it to simply set the directory location.

The publishing activity I described above is performed by our default Publishing dispatch handler. How you replace or subsidize the default behavior to accomplish your task is up to you. A few ideas/options:
  • Remove our Publish dispatch handler and install your own. From then on, your users will not be able to attach ReadyDocs to the Order from the Documents screen, rather, the ReadyDocs they Publish will flow directly to your website by way of your handler. They will no longer be recorded as attachments to the Order.
  • Leave our handler in place and install yours to run before ours, perhaps silently performing both activities or perhaps popping up a dialog that asks the user which activity to perform (yours or our default).
  • Do nothing with packages and handlers - just use our default Publish handler but provide an alternate storage mechanism by providing a class that implements SoftPro.Documents.Storage.IDocumentStorage. This is less flexible but lets you configure where the ReadyDoc PDF files are physically stored when they are published, and how to get to them back when requested inside the Order to which they're attached (all done via URI). For example, you could configure an IDocumentStorage class to push the document to your website when the Order is saved and return a URI that uniquely identifies its location, and then when requested for viewing from within the Order, be able to turn that same URI back into an accessor of the document from your website.
The Select printing subsystem is far more flexible than what is offered in Enterprise, so it might be a good exercise to decide how you'd ideally like your user base to perform the actions you've described from a workflow perspective, at which point perhaps I could help come up with the best alternative(s)...
Shevy
Posts: 48
Joined: Tue Dec 23, 2008 12:21 pm

Re: Retrieving PDF from XML - Transaction Point

Post by Shevy »

I have created a simple PrintDispatchHandler inorder to get started. All it does so far is gives a messagebox with the document name. I put the handler on the "publish" (PrintJobTarget.Publish) button since that is what I had decided to use. However the "publish" button is greyed out so I cant really test this out. How do I go about making this button active?
Mark McKenna

Re: Retrieving PDF from XML - Transaction Point

Post by Mark McKenna »

The state of the Publish button is controlled by profile/preference setting - please check my previous post for details on getting that enabled.

Let us know if you run into any problems getting your handler configured. Sounds like you're making good progress...
Shevy
Posts: 48
Joined: Tue Dec 23, 2008 12:21 pm

Re: Retrieving PDF from XML - Transaction Point

Post by Shevy »

I tried getting into spImage settings. I went into profiles but I couldnt click on "mangers & report preferences" it was greyed out. ANy ideas why this would happen?
ty
Shevy
Posts: 48
Joined: Tue Dec 23, 2008 12:21 pm

Re: Retrieving PDF from XML - Transaction Point

Post by Shevy »

I actually took out the code that says to run for publish

if ((printJob.Properties[PrintJobProperty.Targets] as List<String>).Contains(Enum.GetName(typeof(PrintJobTarget), PrintJobTarget.Publish)))

so now the code should run when I click on "print" or "email".. however nothing seems to be happening. All I put now is a "msgbox" just to see if it is getting there and it is not doing it. What am I doing wrong??
here is my code: ( i basically copied what you put in here).

Code: Select all

Imports System.Runtime.InteropServices
Imports SoftPro.Select.Shell
Imports SoftPro.Select.Shell.Registration
Imports SoftPro.Select.Shell.Printing

''' <summary>
''' Summary description for MyPackage.
''' </summary>
''' <remarks></remarks>
<RegisterPackage("My Company", "My Product", "1.0.0.0", ""), _
RegisterProduct("My Company", "My Product", "1.0", "This is my package.", ""), _
ProvideCommandTable("SaveToWeb.MyPackage.cto"), _
ProvideToolWindow("MyToolWindow", GetType(MyToolWindow), "", WindowLocation.Left, Style:=WindowStyle.None, Transient:=True, Visible:=False), _
Guid(MyPackage.PackageGuidString)> Partial Class MyPackage
    Inherits SoftPro.Select.Shell.Package

    Protected Overrides Sub OnInitialize()
        'Me.RegisterHandler(MyPackage.RibbonButton1, AddressOf Me.RibbonButton1_Invoked)
        MyBase.RegisterPrintDispatchHandler(New PublishToWeb())
    End Sub

    'Private Sub RibbonButton1_Invoked(ByVal sender As Object, ByVal e As EventArgs)

    '    Dim shell As IShell = Me.GetService(Of IShell)()
    '    shell.OpenToolWindow(GetType(MyToolWindow))

    'End Sub

End Class

Imports SoftPro.Select.Shell.Printing
Imports System.IO

Class PublishToWeb
    Inherits PrintDispatchHandler
    Protected Overloads Overrides Function OnHandleDispatched(ByVal printJob As IPrintJob) As Boolean
        ' rip through the individual items in the print job 
        For Each item As IPrintJobItem In printJob.Items
            ' here's the PDF location 
            Dim fi As FileInfo = TryCast(item.Properties("FileLocation"), FileInfo)
            MsgBox(fi.FullName)
        Next

        ' allow the pipeline to continue 
        Return False
    End Function
End Class
Thanks.
Post Reply