Document Queues Automation

<< Click to Display Table of Contents >>

Navigation:  Zetadocs SDK Guide > Creating a Per Tenant Extension >

Document Queues Automation

Zetadocs AutoLink allows you to archive the documents from the Zetadocs Document Queue against the records in Business Central. The logic is usually reliant on use of barcodes and will require a Per Tenant Extension and to be enabled in the Document Queue Settings.

 

Autolink Example

The following code illustrates how use the OnBeforeCapture event to autolink a document in the Zetadocs Document Queue to a Business Central record by barcodes:

 

 

[EventSubscriber(ObjectType::Codeunit, Codeunit::"Zetadocs Customize", 'OnBeforeCapture', '', true, true)]

  local procedure OnBeforeCapture(var onBeforeCaptureHandler: Codeunit "Zetadocs OnBeforeCapture")

  var

      PurchaseHeader: Record "Purchase Header";

      SalesHeader: Record "Sales Header";

      DocQueueNo: Record "Zetadocs Document Queue";

      documentKeys: List of [Text];

      docKey: Text;

      documentBarcodes: List of [Text];

      barcode: Text;

      documentLink: Text;

      barcodeFilter: Text;

      valuePairs: JsonArray;

  begin

      //Get the list of documents

      onBeforeCaptureHandler.GetDocumentIds(documentKeys);

 

      //If we have multiple queues makes sure we're processing the correct document type

      onBeforeCaptureHandler.GetDocumentQueueSettings(DocQueueNo);

      case DocQueueNo."No." of

          'ZDQ0001':

              begin

                  //Business logic to assign the documents to a record

                  foreach docKey in documentKeys do begin

                      onBeforeCaptureHandler.GetDocumentBarcodes(docKey, documentBarcodes);

 

                      // Loop over the barcodes and stop when the required one is found.

                      foreach barcode in documentBarcodes do begin

                          barcodeFilter := CopyStr(barcode, 1, 5);

                          documentLink := CopyStr(barcode, 6);

                          case barcodeFilter of

                              'ZD-SO':

                                  begin

                                      Salesheader.Reset;

                                      SalesHeader."Document Type" := SalesHeader."Document Type"::Order;

                                      SalesHeader."No." := CopyStr(documentLink, 1, MaxStrLen(SalesHeader."No."));

                                      if (Salesheader.Find()) then begin

                                          onBeforeCaptureHandler.SetRecordId(docKey, Salesheader.RecordId);

                                          //Exit the foreach if we have a match

                                          break;

                                      end;

                                  end;

                          end;

                      end;

                  end;

              end;

          'ZDQ0002':

              begin

                  //Business logic to assign the documents to a record

                  foreach docKey in documentKeys do begin

                      onBeforeCaptureHandler.GetDocumentBarcodes(docKey, documentBarcodes);

 

                      // Loop over the barcodes and stop when the required one is found.

                      foreach barcode in documentBarcodes do begin

                          barcodeFilter := CopyStr(barcode, 1, 5);

                          documentLink := CopyStr(barcode, 6);

                          case barcodeFilter of

                              'ZD-PO':

                                  begin

                                      PurchaseHeader.Reset;

                                      PurchaseHeader."Document Type" := PurchaseHeader."Document Type"::Order;

                                      PurchaseHeader."No." := CopyStr(documentLink, 1, MaxStrLen(PurchaseHeader."No."));

                                      if (PurchaseHeader.Find()) then begin

                                          onBeforeCaptureHandler.SetRecordId(docKey, PurchaseHeader.RecordId);

                                          //Exit the foreach if we have a match

                                          break;

                                      end;

                                  end;

                          end;

                      end;

                  end;

              end;

          'ZDQ0003':

              begin

                  //Business logic to give extra logic for automatic processing and form filling

                  foreach docKey in documentKeys do begin

                      onBeforeCaptureHandler.GetDocumentBarcodes(docKey, documentBarcodes);

                      valuePairs := onBeforeCaptureHandler.GetRecognisedKeyValuePairs(docKey);

 

                      //Insert logic based on values of valuePairs and decide the Vendor accordingly

                      onBeforeCaptureHandler.SetVendor(docKey, 'NewCaSup');

                  end;

              end;

      end;

  end;

 

 

Scheduled AutoLink Example

Once covered by AutoLink, the document queue processing can be scheduled using a Business Central Job Queue Entry.

 

To do so, you will need to:

 

Consolidate record information after Zetadocs Capture Example

The following code illustrates how use the OnAfterGenerateCaptureResults event to add Dimension information to a Business Central record processed using Zetadocs Capture based on the information of the record matched, or on the Shipping Address or barcodes. As well as extract the the Job No from the recognised KeyValuePairs and set it on the record lines :

 

 

    [EventSubscriber(ObjectType::Codeunit, Codeunit::"Zetadocs Customize", 'OnAfterGenerateCaptureResults', '', true, true)]

    local procedure OnAfterGenerateCaptureResults(var onAfterGenerateCaptureResultsHandler: Codeunit "Zdd OnAfterGenerateCaptureRes")

    var

        purchaseHeader: record "Purchase Header";

        purchaseLines: Record "Purchase Line";

        orderLine: Record "Purchase Line";

        recId: RecordId;

        shippingAddress: Text;

        barcodes: List of [Text];

        firstBarcode: Text;

        lineDimensionsSet: Boolean;

 recognisedKeyValuePairs: JsonArray;

 jobNo: Text;

    begin

        onAfterGenerateCaptureResultsHandler.GetGeneratedRecordId(recId);

 

        case recId.TableNo of

            38:

                begin

                    if (purchaseHeader.Get(recId)) then begin

                        purchaseLines.SetFilter(purchaseLines."Document No.", purchaseHeader."No.");

                        if (purchaseLines.Find('-')) then

                            repeat

                                if (orderLine.Get("Purchase Document Type"::Order, purchaseLines."Order No.", purchaseLines."Order Line No.")) then begin

                                    purchaseLines.Description := orderLine.Description;

                                    SetDimension(1, orderLine."Shortcut Dimension 1 Code", purchaseLines);

                                    SetDimension(2, orderLine."Shortcut Dimension 2 Code", purchaseLines);

                                    purchaseLines.Modify();

                             

                             if (jobNo <> '') then begin

                                 purchaseLines."Job No." := jobNo;

                                 purchaseLines."Job Task No." := CopyStr(jobNo, 1, MaxStrLen(PurchaseHeader."No."));

                                       purchaseLines.Modify();

                             end;

                                    lineDimensionsSet := true;

                                end;

                            until purchaseLines.Next() = 0

                    end;

 

                    if (lineDimensionsSet = false) then begin

                        shippingAddress := onAfterGenerateCaptureResultsHandler.GetShippingAddressInput();

 

                        if shippingAddress <> '' then begin

                            if shippingAddress.Contains('Ashford Street London W2 8HG') then begin

                                SetDimension(1, 'ADM', purchaseHeader);

                            end else begin

                                SetDimension(1, 'PROD', purchaseHeader);

                            end;

                            purchaseHeader.Modify();

                        end;

 

                        onAfterGenerateCaptureResultsHandler.GetDocumentBarcodes(barcodes);

                        if (barcodes.Count <> 0) then begin

                            firstBarcode := barcodes.Get(1);

                            if firstBarcode.Contains('SO-') then begin

                                SetDimension(1, 'ADM', purchaseHeader);

                            end else begin

                                SetDimension(1, 'PROD', purchaseHeader);

                            end;

                            purchaseHeader.Modify();

                        end;

                    end;

                end;

        end;

    end;

 

    local procedure SetDimension(ShortcutDimensionIndex: integer; ShortcutDimensionValueCode: Code[20]; var PurchaseLine: Record "Purchase Line")

    begin

        // PurchaseHeader.SetHideValidationDialog(true);

        //Values from Demo Business Central

        // [1]:'DEPARTMENT'

        // [2]:'PROJECT'

        // [3]:'CUSTOMERGROUP'

        // [4]:'AREA'

        // [5]:'BUSINESSGROUP'

        // [6]:'SALESCAMPAIGN'

        // [7]:''

        // [8]:''

 

        case ShortcutDimensionIndex of

            1:// Set Shortcut 1

                if PurchaseLine."Shortcut Dimension 1 Code" <> ShortcutDimensionValueCode then begin

                    PurchaseLine."Shortcut Dimension 1 Code" := ShortcutDimensionValueCode;

                    PurchaseLine.VALIDATE("Shortcut Dimension 1 Code");

                end;

            2:// Set Shortcut 2

                if PurchaseLine."Shortcut Dimension 2 Code" <> ShortcutDimensionValueCode then begin

                    PurchaseLine."Shortcut Dimension 2 Code" := ShortcutDimensionValueCode;

                    PurchaseLine.VALIDATE("Shortcut Dimension 2 Code");

                end;

            else begin

                PurchaseLine.ValidateShortcutDimCode(ShortcutDimensionIndex, ShortcutDimensionValueCode);

            end;

        end;

    end;

 

    local procedure SetDimension(ShortcutDimensionIndex: integer; ShortcutDimensionValueCode: Code[20]; var PurchaseHeader: Record "Purchase Header")

    begin

        PurchaseHeader.SetHideValidationDialog(true);

 

        //Values from Demo Business Central

        // [1]:'DEPARTMENT'

        // [2]:'PROJECT'

        // [3]:'CUSTOMERGROUP'

        // [4]:'AREA'

        // [5]:'BUSINESSGROUP'

        // [6]:'SALESCAMPAIGN'

        // [7]:''

        // [8]:''

 

        case ShortcutDimensionIndex of

            1:// Set Shortcut 1

                if PurchaseHeader."Shortcut Dimension 1 Code" <> ShortcutDimensionValueCode then begin

                    PurchaseHeader."Shortcut Dimension 1 Code" := ShortcutDimensionValueCode;

                    PurchaseHeader.VALIDATE("Shortcut Dimension 1 Code");

                end;

            2:// Set Shortcut 2

                if PurchaseHeader."Shortcut Dimension 2 Code" <> ShortcutDimensionValueCode then begin

                    PurchaseHeader."Shortcut Dimension 2 Code" := ShortcutDimensionValueCode;

                    PurchaseHeader.VALIDATE("Shortcut Dimension 2 Code");

                end;

            else begin

                PurchaseHeader.ValidateShortcutDimCode(ShortcutDimensionIndex, ShortcutDimensionValueCode);

            end;

        end;

    end;

 

    local procedure GetFormRecogniserValue(RecognisedKeyValuePairs: JsonArray; searchKey: Text)Text

  var
 numItems: Integer;

 Index: Integer;

 Jtoken: JsonToken;

 tokenTemp: JsonToken;

 recognisedValue: Text;

 valueTemp: Text;

    begin

 numItems := RecognisedKeyValuePairs.Count;

 Index := 0;

 if (numItems > 0then begin

     repeat begin

         RecognisedKeyValuePairs.Get(Index, JToken);

         if (Jtoken.AsObject().Get('Key', tokenTemp)) then begin

             valueTemp := tokenTemp.AsValue().AsText().ToUpper();

 

             if (valueTemp.StartsWith(searchKey.ToUpper())) then begin

                 if (Jtoken.AsObject().Get('Value', tokenTemp)) then recognisedValue := tokenTemp.AsValue().AsText();

             end;

         end;

         Index := Index + 1;

     end

     until (numItems = Index) or (recognisedValue <> '');

 exit(recognisedValue);

    end;

 

 

 

Refine the document information available for Zetadocs Capture Ap Automation Example

The following code illustrates how use the OnBeforeCapture event to update the Vendor name based associated with a document to streamline the automatic processing of the documents :

 

 

    [EventSubscriber(ObjectType::CodeunitCodeunit::"Zetadocs Customize", 'OnBeforeCapture''', true, true)]

    procedure OnBeforeCapture(var onBeforeCaptureHandler: Codeunit "Zetadocs OnBeforeCapture")

    var

        documentKeys: List of [Text];

        docKey: Text;

        valuePairs: JsonArray;

        valueText: Text;

    begin

        //Get the list of documents

        onBeforeCaptureHandler.GetDocumentIds(documentKeys);

 

        //Business logic to give extra logic for automatic processing and form filling

        foreach docKey in documentKeys do begin

            onBeforeCaptureHandler.GetDocumentBarcodes(docKey, documentBarcodes);

            valuePairs := onBeforeCaptureHandler.GetRecognisedKeyValuePairs(docKey);

 

            //Insert logic based on values of valuePairs and decide the Vendor accordingly

            valueText := GetFormRecogniserValue(valuePairs, 'Subcontractor');

            onBeforeCaptureHandler.SetVendor(docKey, valueText);

        end;

    end;

 

    local procedure GetFormRecogniserValue(RecognisedKeyValuePairs: JsonArray; searchKey: Text)Text

  var
 numItems: Integer;

 Index: Integer;

 Jtoken: JsonToken;

 tokenTemp: JsonToken;

 recognisedValue: Text;

 valueTemp: Text;

    begin

 numItems := RecognisedKeyValuePairs.Count;

 Index := 0;

 if (numItems > 0then begin

     repeat begin

         RecognisedKeyValuePairs.Get(Index, JToken);

         if (Jtoken.AsObject().Get('Key', tokenTemp)) then begin

             valueTemp := tokenTemp.AsValue().AsText().ToUpper();

 

             if (valueTemp.StartsWith(searchKey.ToUpper())) then begin

                 if (Jtoken.AsObject().Get('Value', tokenTemp)) then recognisedValue := tokenTemp.AsValue().AsText();

             end;

         end;

         Index := Index + 1;

     end

     until (numItems = Index) or (recognisedValue <> '');

 exit(recognisedValue);

    end;

 

Consolidate record information after Zetadocs Capture Example for VAT exempt companies

The following code illustrates how use the OnAfterGenerateCaptureResults event to add the Tax amount directly in the line Direct Cost to bypass the VAT/TAX handling from Business Central:

 

    [EventSubscriber(ObjectType::Codeunit, Codeunit::"Zetadocs Customize", 'OnAfterGenerateCaptureResults', '', true, true)]

    local procedure SpreadTaxProportionallyToLineTotal(var onAfterGenerateCaptureResultsHandler: Codeunit "Zdd OnAfterGenerateCaptureRes")

    var

        purchaseHeader: Record "Purchase Header";

        purchaseLines: Record "Purchase Line";

        recId: RecordId;

        taxAmount: Decimal;

        adjustedTax: Decimal;

        invoiceTotal: Decimal;

        lineAdjustment: Decimal;

        previousLineAmount: Decimal;

    begin

        taxAmount := onAfterGenerateCaptureResultsHandler.GetInvoiceTax();

 

        onAfterGenerateCaptureResultsHandler.GetGeneratedRecordId(recID);

        purchaseHeader.get(recId);

        purchaseLines.SetFilter("Document No.", purchaseHeader."No.");

        purchaseLines.SetFilter(Quantity, '<>0');

 

        if (purchaseLines.Find('-')) then

            repeat

                case purchaseLines.type of

                    purchaseLines.type::"G/L Account",

                    purchaseLines.type::Item,

                    purchaseLines.type::"Fixed Asset":

                        begin

                            invoiceTotal := invoiceTotal + purchaseLines.amount;

                        end;

                end;

            until purchaseLines.Next() = 0;

 

        if (invoiceTotal > 0) then begin

            if (purchaseLines.Find('-')) then

                repeat

                    case purchaseLines.type of

                        purchaseLines.type::"G/L Account",

                        purchaseLines.type::Item,

                        purchaseLines.type::"Fixed Asset":

                            begin

                                lineAdjustment := taxAmount * purchaseLines.amount / invoiceTotal;

                                previousLineAmount := purchaseLines."Line Amount";

                                purchaseLines."Direct Unit Cost" := purchaseLines."Direct Unit Cost" + (lineAdjustment / purchaseLines.Quantity);

                                purchaseLines.Validate("Direct Unit Cost");

                                purchaseLines.Modify();

                                adjustedTax := adjustedTax + (purchaseLines."Line Amount" - previousLineAmount);

                            end;

                    end;

                until purchaseLines.Next() = 0;

        end;

 

        if ((taxAmount - adjustedTax) <> 0) then begin

            if (purchaseLines.Find('-')) then

                repeat

                    case purchaseLines.type of

                        purchaseLines.type::"G/L Account",

                        purchaseLines.type::Item,

                        purchaseLines.type::"Fixed Asset":

                            begin

                                purchaseLines."Direct Unit Cost" := purchaseLines."Direct Unit Cost" + ((taxAmount - adjustedTax) / purchaseLines.Quantity);

                                purchaseLines.Validate("Direct Unit Cost");

                                purchaseLines.Modify();

                            end;

                    end;

                until (purchaseLines.Next() = 0) or ((taxAmount - adjustedTax) = 0);

        end;

    end;