Core: submission processing

Once a form is submitted by the user, a number of actions take place to process this submission. The complete process is shown below.

../../../_images/submission_flow.png

Depending on the plugins that are active, some actions are skipped (boxes with the dotted borders). Some actions are blocking but most actions have a fall through mechanism to prevent the user from waiting for feedback for too long.

Globally, the various actions and plugin categories are processed in order:

  1. If applicable, an appointment is created. If this fails, the submission is blocked and the user sees an error message and can try again (note: this step is deprecated and not needed for the new appointment flow).

  2. Pre-registration step. Each registration plugin can perform pre-registration task, like for example generating and setting a submission reference ID. If no registration backend is configured, then an internal ID is generated and set on the submission.

  3. A PDF is created that the user can download. This PDF is also uploaded to most registration backends, depending on the plugin.

  4. If a registration backend is configured, the submission is registered.

  5. The confirmation page is shown, containing appointment information if applicable and the registration or internal ID. If payment is due, a payment link is also shown to start the payment process.

  6. If the user clicks on the payment link, the payment process starts. If this process is not completed in a reasonable amount of time, it is assumed the user did not pay. If payment is completed within or after the timeout, the registration is updated with the payment status.

  7. If no payment was required, or payment was completed, or the payment timeout was reached, a confirmation email is sent. Depending on all the results of the previous actions, the confirmation email shows different contents.

The confirmation email can show submission details, appointment details (including links to cancel or change the appointment), payment details (including a link to pay if not done so already), cosign details and custom information as part of the form.

Under the hood

The steps described above are orchestrated by openforms.submissions.tasks.on_post_submission_event(). This method schedules the following tasks/chains:

  • Task openforms.submissions.tasks.user_uploads.cleanup_temporary_files_for()

  • A chain with the following tasks:

    • openforms.appointments.tasks.maybe_register_appointment()

    • openforms.registrations.tasks.pre_registration()

    • openforms.submissions.tasks.pdf.generate_report_task()

    • openforms.registrations.tasks.registration()

    • openforms.payments.tasks.update_submission_payment_status()

    • openforms.submissions.tasks.finalise_completion() which schedules the following tasks (not in a chain):

      • openforms.submissions.tasks.schedule_emails()

      • openforms.submissions.tasks.cleanup.maybe_hash_identifying_attributes()

The IDs of the tasks scheduled in the chain are saved in a model openforms.submissions.models.PostCompletionMetadata which is linked (foreign key) to the submission. With the task IDs, we can inspect the status of the tasks and communicate the status of the chain back to the frontend, so that the confirmation page can be shown.

Method openforms.submissions.tasks.on_post_submission_event() is not only called upon completing a submission, but also when the following events happen:

  • Payment is completed

  • Submission is cosigned

  • A retry flow is triggered (either because the registration failed or because the payment status update failed).

There is a possibility that the payment and the cosign happen at the same time. Since the task openforms.submissions.tasks.schedule_emails() is a Celery Once task, this should not lead to two confirmation emails being sent at the same time. Since the content of the confirmation email is deduced by the state of the submission, even in this edge case the email body should contain the correct information.