Issue date not after due date check

Another very important data integrity check is to ensure that the issue date is not after due date. If the dates are not chronologically correct, a warning message should be shown to the operator.

This code example assumes you have the following field IDs in your extraction schema:

  • "date_issue" for capturing the issue date
  • "date_due" for capturing the due date

Moreover, the serverless function should be configured to get notifications on "user_update" action and the function should be assigned to some queue.

// This serverless function example can be used for annotation_content events
// (e.g. user_update action). annotation_content events provide annotation
// content tree as the input.
//
// The function below shows a warning message to the operator if Issue date is
// after Due date.

// --- ROSSUM HOOK REQUEST HANDLER ---

// The rossum_hook_request_handler is an obligatory main function that accepts
// input and produces output of the rossum serverless function hook. Currently,
// the only available programming language is Javascript executed on Node.js 12 environment.
// @param {Object} annotation - see https://api.elis.rossum.ai/docs/#annotation-content-event-data-format
// @returns {Object} - the messages and operations that update the annotation content

exports.rossum_hook_request_handler = ({
  annotation: {
    content
  }
}) => {
  try {


    const [dateIssueDatapoint] = findBySchemaId(
      content,
      'date_issue',
    );
    
    const [dateDueDatapoint] = findBySchemaId(
      content,
      'date_due',
    );

    messages = [];
    
    dateIssueString = dateIssueDatapoint.content.normalized_value;
    dateDueString = dateDueDatapoint.content.normalized_value;
    
    if(dateIssueString && dateDueString){
    
      [year, month, day] = dateIssueString.split("-");
      dateIssue = new Date(year=year, month=month, day=day);
      
      [year, month, day] = dateDueString.split("-");
      dateDue = new Date(year=year, month=month, day=day);
      
      if(dateIssue > dateDue){
        
        messageText =  `Issue date (${dateIssueDatapoint.content.value}) should not be after Due date (${dateDueDatapoint.content.value})`
        
        messages.push(
          createMessage(
            'warning',
            messageText,
            dateIssueDatapoint.id
            )
          );
         
        messages.push(
          createMessage(
            'warning',
            messageText,
            dateDueDatapoint.id
            )
        );
      }
    }
    

    // Return messages and operations to be used to update current annotation data
    return {
      messages
    };
  } catch (e) {
    // In case of exception, create and return error message. This may be useful for debugging.
    const messages = [
      createMessage('error', 'Serverless Function: ' + e.message)
    ];
    return {
      messages,
    };
  }
};

// --- HELPER FUNCTIONS ---

// Return datapoints matching a schema id.
// @param {Object} content - the annotation content tree (see https://api.elis.rossum.ai/docs/#annotation-data)
// @param {string} schemaId - the field's ID as defined in the extraction schema(see https://api.elis.rossum.ai/docs/#document-schema)
// @returns {Array} - the list of datapoints matching the schema ID

const findBySchemaId = (content, schemaId) =>
  content.reduce(
    (results, dp) =>
    dp.schema_id === schemaId ?
    [...results, dp] :
    dp.children ?
    [...results, ...findBySchemaId(dp.children, schemaId)] :
    results,
    [],
  );

// Create a message which will be shown to the user
// @param {number} datapointId - the id of the datapoint where the message will appear (null for "global" messages).
// @param {String} messageType - the type of the message, any of {info|warning|error}. Errors prevent confirmation in the UI.
// @param {String} messageContent - the message shown to the user
// @returns {Object} - the JSON message definition (see https://api.elis.rossum.ai/docs/#annotation-content-event-response-format)

const createMessage = (type, content, datapointId = null) => ({
  content: content,
  type: type,
  id: datapointId,
});

// Replace the value of the datapoint with a new value.
// @param {Object} datapoint - the content of the datapoint
// @param {string} - the new value of the datapoint
// @return {Object} - the JSON replace operation definition (see https://api.elis.rossum.ai/docs/#annotation-content-event-response-format)

const createReplaceOperation = (datapoint, newValue) => ({
  op: 'replace',
  id: datapoint.id,
  value: {
    content: {
      value: newValue,
    },
  },
});