Skip to content

Developer Notes

Fundamental Design

The main goal was to achieve a decoupled solution. Hence, the solution started as Stand-alone and was later integrated. Furthermore, there was an intent to have a generic type of integration in any document, and for the Integration Document to contain as little information about the Questionnaire as possible. Currently, only the id is stored in the Integration Document and two tables were created for that purpose:

  • QuestionnaireInfo: field code (Questionnaire Id)
  • QuestionnaireAnswerInfo: field questionnaireAnswerId (Questionnaire Answer Id)

This type of solution presented a lot of challenges, since there was an intention of a seamless integration in terms of Creation/Presentation/Saving/Workflows of two separate documents acting as one. There was also a strong focus to minimize the performance impact of the solution, since a single document could have many integrated documents. For all the aforementioned reasons there was a need to create auxiliary Tables to achieve this integration.

Performance Concern and Lazy Creation

There was a strong concern about performance hindrance due to the nature of the decoupled solution, mainly for the Questionnaire Answers.

Looking into the QuotationReceiverDoc, it is possible to see that the creation of a Questionnaire Answer could be exponential since it's a result from the multiplication of the number of Items by the number of Suppliers. This could mean that certain phases would result in bulk operations of a considerate amount of documents, creating time consuming bottlenecks that could seriously affect User Experience or even functional viability.

Several measures were enforced to optimize performance and avoid the bottlenecks previously described:

  • The main measure adopted was Lazy Creation for Questionnaire Answers. For this purpose, a UUID is generated and stored in the Integration Table, representing a Questionnaire Answer document. Only when the user first loads the Questionnaire Answer in an editable state will the actual document be created.
  • Whenever possible the Integration Tables are used instead of the documents, since they are much faster, especially for bulk operations. This measure is directly responsible for the fields present in the Integration Tables.

Integration Tables

For the Questionnaire the QuestionnaireIntegration Table was created with the following fields:

  • documentId
  • integrationType
  • integrationDocumentId
  • versionId
  • editVersionId (used when a user cancels edition, to restore to the pre-editing state)
  • hasRequiredQuestions (used to set initial notification of the Questionnaire Answer)
  • integrationStatus (described in Questionnaire Configurer chapter)
  • documentStatus (described in Questionnaire Configurer chapter)
  • active (boolean to indicate if document is active)

For the Questionnaire Answer the QuestionnaireAnswerIntegration Table was created with the following fields:

  • documentId
  • integrationType
  • integrationDocumentId
  • versionId
  • parentDocumentId (Questionnaire that created Answer)
  • parentVersionId (Questionnaire version that created the Answer, used to check if the Questionnaire changed requiring the creation of a new Answer)
  • notification (described in Questionnaire Answer chapter)
  • integrationStatus (described in Questionnaire Answer chapter)
  • documentStatus (described in Questionnaire Answer chapter)
  • active (boolean to indicate if document is active)

History and Versioning

To maintain coherence when looking at the Integration Document history page view, two tables were created to connect the corresponding versions of documents:

  • QuestionnaireIntVersion (for the Questionnaire)
  • QuestionnaireAnswerIntVersion (for the Questionnaire Answer. In some cases a submission could have an invalid Questionnaire Answer because of Lazy Creation or rejection/cancellation by the Integration Document. In that case an entry is still created in the Table with a null versionId and status. In terms of showing that specific entry to a user, a blank Questionnaire Answer is created according to the parentDocumentId and the parentVersionId)

Dangling Questionnaires

An integrated Questionnaire is created dangling until the Integration Document performs a save. However if this save does not take place, the Questionnaire will remain dangling.

At this moment there is no routine or macro to clean these dangling documents, but one should be considered in the future.

Integration Workflow

The state of the Questionnaires is defined when the SourcingFlowDoc is saved.

The state of the Answers is defined by the QuotationReceiver Send Quotation action or by some of the BPMN Service tasks.

Questionnaire Configurer

Depending on the save action:

  • Create/Submit: draft Questionnaires become final.
  • Edit: same as Create/Submit, but a pre-editing state is recorded in case there is a need to revert back to it.
  • Approve: same as Create/Submit, the editing state is cleared since it was approved.
  • Cancel: final state is reverted to a previously recorded pre-editing state if different.
  • Remaining (to this date: Reject, Reset, NewRound, Suspend, Rollback, System, NoAction): draft is discarded and previously final state is assumed.

Questionnaire Answer

Depending on the QuotationReceiver Send Quotation action:

  • Answer: draft Questionnaire answers become final.
  • Remaining (to this date: Create, Award, Evaluate, System, NoAction): nothing happens.

Several BPMN service tasks discard draft Answers, setting the integration status to Revert:

  • EndPhase: called at the end of every Phase Workflow.
  • EndQuotationAnswers: called when Receiving is over either by forced withdraw or by time limit.
  • ResetQuotation: called when there is a new round or a reset.
  • NewNegotiation: called when there is a new round in the Negotiation phase.

Questionnaire Answer Read and Answer Date

Read and Answer date is filled in the same manner as the Integration Document, which means they are only filled when the user reading is a supplier or it's contact.

Logic Differences from Integration Documents

Negotiation Phase

Although the Questionnaire Answer mimics the behaviour of it's Integration Document. Internally, there is a difference in the Negotiation Phase. In this phase a new QuotationReceiverDoc is created and answers from the First Offer are copied. However, it was decided that the same Questionnaire Answers would be used for the new Document since it poses no conflict with previous workflows.

Edit in Quotation Process Flow

It is possible to edit a SourcingFlow Process while in Receiving Quotation/Negotiation. Currently, if the answer deadline is changed any saved Drafts in the QuotationReceiverDoc are discarded. However, it was deemed that this behaviour was not ideal in terms of User Experience, and since it is not necessary for the Questionnaire Answer it wasn't adopted. Hence, the Questionnaire Answer Drafts are not affected by SourcingFlow edition while in Receiving state.

Edit First Offer

The Edit First Offer flow deviates slightly from the SourcingFlow. There was a goal to make the Questionnaire feature consistent with the Edit First Offer behaviour.

The Questionnaire Answers are presented the same way as an History pageview, however the answers are editable. All changes are contained in the Edit First Offer pageview (stored in the DOM). And only after confirming edition will they be sent to the back-end. This means that refreshing the page will result in loss of changes, which is consistent with the page itself.

If a user "Confirms Edition", any current Questionnaire Answer Drafts will be discarded and only the last valid submitted Answer will be considered. This is consistent with the QuotationReceiverDoc behaviour.