• RE: REST API : Document searches by fields

    Aurelien,

    I think if the query did work directly against the cabinet, it would just use an encoded "q" expression, not POST data. The problem is, it just doesn't work. I tried searching for a past thread about the error I got with GetFromDocumentsForDocumentsQueryResultAsync() when trying to use the "query" parameter, but I cannot find it anywhere (it was on the old forums). It looks like they still have not gotten it to work.

    I went ahead and tried a query again to recall what the error was (on 6.11 on-premise) It is:
     
    500 Internal Server Error (The given key was not present in the dictionary.)

    It doesn't matter what I try for the query parameter -- if it is a non-empty string I get the above error, valid expression or not.

    The count parameter does work, though, to limit the number of records returned. So, if you just want all or some the files in a file cabinet, it is the method to use so that you don't need to mess with a dialog GUID.

    Thanks,
    Joe Kaufman


     
  • RE: REST API : Document searches by fields

    Aurelien,

    If the "q" is like the "q" parameter for URL integration, here is what I have in my comments about how to form the query parameter:
     
    Field names in queries are case sensitive! Field names (in the database) are usually ALL CAPS.
    The actual database field name of a field can be viewed in the DocuWare Administration desktop
    application. Queries place field name in square brackets and the value on double-quotes.
    Though, for numeric fields, the quotes appear to be optional. Operators can have whitespace
    around them. Here are example query expressions:
    
    [DWDOCID]=123    (This will query by the internal DocuWare document ID.)
    [CUST_NO] = "WA60"    (This will query the field "CUST_NO", trying to exactly match "WA60".)
    [LASTNAME] LIKE "K*"    (Wildcard search -- note use of "*" instead of "%" for wildcard character.)
    [SHIPTO_STATE] = EMPTY()    (Queries SHIPTO_STATE for empty values ("EMPTY()" must be uppercase).)
    [BILLTO_STATE] = NOTEMPTY()    (Queries BILLTO_STATE for non-empty values ("NONEMPTY()" must be uppercase).)
    [DocuWareFulltext] = "find this string"        (Full-text search.)
    [DWSTOREDATETIME] > 2017-06-14 19:45:31        (Date/time expression *** CONVERT TO UTC ***)
    [START_DATE] >= 2016-06-01 AND [START_DATE] <= 2016-08-01    (Boolean conditional, checking date field over a date range, inclusively.)
    
    Expressions can be joined by AND or OR and can be qualified with NOT. Delimiters around string
    values MUST be double-quotes. Also, the conditional statements and compound keywords (e.g. LIKE, AND, OR, etc.)
    need to be capitalized as well.
    
    *** SPECIAL NOTE WHEN USING DATE/TIME FIELDS ***  Date/time fields are stored in DocuWare as UTC timestamps.
    While queries in the web client or Platform SDK allow the use of local date/time formats, URL Integration
    queries appear to use the date/times passed in as-is and compare against the stored UTC timestamps.
    So, if you are using date/time fields in your query, the date/time values need to be converted to UTC
    to get accurate results.

    Additionally, the query parameter needs to be URL encoded, doing whatever something like System.Web.HttpServerUtility.UrlTokenEncode() does in .NET. Not sure how I figured that out, but that's what the code (that works) says.

    When it comes to the call itself, I don't use the resource you list. In fact, I think I tried it in version 6.11 and it didn't work. All I could do with that resource was to return ALL documents from the file cabinet. If I tried to add a query parameter, the call threw a strange error (in .NET).

    So, I use the following resource, and it works from Visual FoxPro:
     
    /DocuWare/Platform/FileCabinets/{cab GUID}/Query/DialogExpression?dialogId={dialog GUID}&count=2100000000

    This works through a dialog, so it is a bit more of a pain to use since you have to know the GUID of the file cabinet and the search dialog.

    Where is the query, you might ask? When using the above resource, you do it as a POST, not a GET, and the query is in the POST data. Here is an example of POSTed XML:
     
    <?xml version="1.0" encoding="utf-8"?>
    <DialogExpression xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:xsd="http://www.w3.org/2001/XMLSchema"  Operation="And"  xmlns="http://dev.docuware.com/schema/public/services/platform">
        <Condition DBName="COMPANY">
            <Value>bell</Value>
        </Condition>
    </DialogExpression>

    You basically just construct XML with field names and values, and the values can be wildcards or system keywords like EMPTY() and NOTEMPTY(). POST this content to the resource and you get back an XML result with all the found document records. You'll have to parse that out however you see fit into whatever result you need.

    Lots of trial and error on this stuff. One way to learn about what is going on under the hood is to do operations in C#/.NET using the libraries that make such operations easier to construct (syntactically). Then, if you watch network traffic with something like Fiddler you can see what the raw HTTP calls look like (I can, anyway, as our server is HTTP, not HTTPS -- not sure what happens with HTTPS). IIRC, posted data in those calls is usually JSON instead of XML, which you can totally use if you are more comfortable with JSON. I've had better luck posting XML for some reason.

    Again, this is all on 6.11, an on-premise installation.

    Hope this helps!

    Thanks,
    Joe Kaufman

     
  • RE: Clip like in the web client, but from Platform SDK API?

    Seth and Josef,

    Thank you! Seth, yes, I have that Merge code working, though not in FoxPro. I may have to write some of these routines in C# instead. I guess I can go ahead and just upload all documents to their final destination, settling on the first one as the "main" document. Then Merge them together once they are all up there. At this point I don't really see why I was so dead set against it, especially if the starting document retains its ID (the documentation says a new document is created, but that must not really be the case, except that of course the document is different once it has stuff clipped to it...

    Thanks,
    Joe Kaufman
  • RE: Clip like in the web client, but from Platform SDK API?

    Seth,

    Yes. I want to upload a "start" document to a file cabinet, then clip additional documents to the back of that one (they are volumes of a study).

    How are you clipping documents to the back of another via the API? The "Merge" operation? Are you clipping documents from one file cabinet to a document in a different file cabinet? Or do you upload the CSV to the same cabinet then merge them?

    That is interesting, what you say about the document ID changing if you clip to the front. In my tests, I can clip to the front of back (when using the web client) and the starting document retains its ID no matter what I do. Now, if I split out the separate clipped parts then all documents get a new ID, obviously.

    If you have sample code of what you are doing, that would be great. I wanted to avoid having to fully upload the additional files to the cabinet (with indexes) just to clip them and have the indexes not mean anything. That is why I wanted to clip documents in a document tray (no indexing required) to a document stored in a file cabinet. Since the web client can do it, I assumed there must be a cleaner way to do it via the Platform SDK API. If I do end up just needing to upload everything fully into a file cabinet (with indexes) and then merge them there it wouldn't be the end of the world, I don;t suppose.

    Thanks,
    JoeK
  • Clip like in the web client, but from Platform SDK API?

    Hey all,

    Since I got no response on the other forum, I figured I'd ask a single question more explicitly here.

    All of this is on DocuWare 6.11, on-premise.

    When using the web client, you can clip documents to an existing document by right-clicking on the document and selecting the "Clip" option (as depicted in the first attached image).

    After selecting that option, the Clipping operation is made available via a two-pane screen with the starting document on the top and places to pull in other documents (to clip) on the bottom (e.g. a Document Tray). The second attached image depicts this interface.

    So far, so good. You can drag documents to clip in front or behind the starting document, then click the yellow "Clip" button to clip everything together in the order you have assembled. It's really quite nice. The starting document retains all of its indexes, and the clipped document is tacked on back (or front). In my testing, it doesn't even change the Document ID of the starting document. Plus, you can ask to preserve clipped documents in their source tray instead of deleting them.

    My question is this: How do I perform this operation via the Platform SDK (API?) Is it possible, or is this functionality only provided via the web client for some reason? Various "Merge" and "Transfer" functions exist in the Platform SDK, but merging involves a single file cabinet GUID. There is no way a function call involving one GUID can take documents from one place and clip them to a document in another place. Transfer functions allow that sort of thing but there is no clip functionality built into that. Additionally, the merge functions are clear to state a new document is created (new ID) and that the documents involved in the merge are deleted from the system. What the web client does is apparently a mix of transferring and merging all in one, and it doesn't change the starting document's ID. It even offers the ability to preserve the documents being clipped.

    Can I do this in the Platform SDK API, and if so, what are the functions I should be looking for?

    If I can't do it via the Platform SDK, is my only route to place all documents into a document tray, clip them together in the tray, then store the merged document to a file cabinet? I think I can do that now that I have figured out how to upload to a tray via the API, it just seems far less elegant than what the web client offers natively.

    Thanks,
    Joe Kaufman
  • RE: Platform call to upload document to Document Tray

    Hey all,

    I'd still appreciate any insight folks can give on my OP, but for now I have written a C# routine that is callable from FoxPro, and I can upload a document to a Document Tray successfully.

    I think the issue for non-.NET tools is that the "Id" for document trays is very strange (discovered it from the .NET side). File cabinets have an Id equivalent to their Guids, but a document tray puts a "b_" in front of their Guid, resulting in an Id that does not meet Guid standards. If I try to manually add the "b_" in front and upload a document (from FoxPro), I get an error about the Guid being malformed.

    Things work in .NET because there the FileCabinet type is used for these method calls -- can't do that with regular HTTP POSTs.

    And my other questions remain. For example, how do I clip a document from a document tray to a document already stored in a file cabinet in .NET? I cannot find any examples except the "merge" and "transfer" examples. As I said before, I don't want to do a file cabinet-based merge because I don't want to have to store documents in a file cabinet just to clip them and delete them (plus it creates a whole new document instead of just clipping onto an existing one). "Transfer" examples do not appear to allow clipping, just movement.

    I'd like to be able to emulate the "Clip" functionality from the right-click menu in the web client, just via the Platform SDK. Can anyone help? How are other people automating these clip processes?

    Thanks,
    Joe Kaufman
  • Platform call to upload document to Document Tray

    Hey all,

    I am trying to upload a document to a document tray via the Platform SDK. We have been uploading documents to file cabinets for a couple years now, no problems. That works in both C# and Visual FoxPro.

    According to the examples here:

    https://developer.docuware.com/dotNet_CodeExamples/57da87ed-111c-4f78-96e9-75d3b9462ce9.html

    namely, the UploadSingleFileToBasket() method, a document tray is treated like a file cabinet, and an upload works the same way. You just don't bother indexing the uploaded document because it hasn't been stored yet.

    So, I figured out how to get the GUID for the document tray itself (not the backing file cabinet), and I tried using that guid to upload a file. The call succeeds (no HTTP error) but the resulting response has the following process error in it:

       FileCabinet with id <guid> is not assigned to the user

    The document is not in the document tray, either. The authenticated user has rights to the document tray I am using both explicitly and via Role. Yet it comes back saying it "is not assigned to the user". What does this mean?

    The bottom line is that I want to upload a file to a document tray instead of a file cabinet. Why? Because I want to then clip the document to an existing document already stored in a file cabinet (like the way it can be done manually via the right-click "Clip" option in the web client. I don't want to do a full "merge" operation where two documents in a file cabinet are merged and then deleted. I want to simply clip a new document to an existing document. If there is a better way of doing that, I'm all ears. We have to have this working because we are about to receive thousands of documents from an external scanning vendor, and I need to upload the first volume of a document to a file cabinet and then clip additional volumes to the original. This needs to be automated, obviously.

    Finally, I am wondering how people find the correct guid for a document tray? We name all of our document trays with a unique name, but that is not a requirement in DocuWare. You could have 800 trays, all named "Inbox", if you want. I just created three trays, all with the name "joek", all backed by the same file cabinet, and all with the exact same user permissions. There is literally no way to tell them apart, aside from each having a unique GUID. How would one automate uploads to various document trays (i.e. some sort of automated, centralized document distribution point) when there is no way to distinguish them uniquely? I guess we just have to be careful to name them distinctly?

    Thanks for any help anyone can offer.

    Thanks,
    Joe Kaufman
  • RE: IE vs. Chrome Performance After Upgrade to 7.1

    Teresa,

    You just know I am going to start with the obligatory, "Why on Earth are they using IE?" It is old and broken and insecure... I assume there is some Silverlight requirement in play such that the client cannot standardize on Chrome or Firefox?

    Speaking of Firefox, how does DocuWare perform on Firefox and Chrome? Edge? Edge would be the heir apparent to IE, though I think it was pretty much created new from the ground up. It would be interesting to see how they all perform relative to each other.

    Sorry I cannot be of more help -- we are on 6.11 and all browsers seem to work OK. We have to use IE for things like setting up Import Configs, since that is still in Silverlight in version 6.11.

    Thanks,
    Joe Kaufman
  • RE: .NET API - Execute a Query using Dialog expression

    Judging by the literals used in URL integration queries (and just tested using a dialog query), it looks like dates need to be of the format:

    "YYYY-MM-DD", as in, "2019-08-01" for August 1, 2019.

    You pass the date value in as a string formatted in that way. For DateTime values, you use:

    "YYYY-MM-DD HH:mm:ss", as in, "2019-08-09 17:32:39".

    Be aware that DateTime fields are always stored with UTC time. That goes for system fields as well as user-defined fields.

    Good luck,
    Joe Kaufman
  • RE: User Long Name

    Seth,

    Additionally, the full name can be found in the "settings" field of that same user record, embedded in the XML.

    Thanks,
    Joe Kaufman