django-forms-workflows 0.64.2__tar.gz → 0.65.1__tar.gz
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- {django_forms_workflows-0.64.2 → django_forms_workflows-0.65.1}/PKG-INFO +1 -1
- {django_forms_workflows-0.64.2 → django_forms_workflows-0.65.1}/django_forms_workflows/admin.py +4 -2
- {django_forms_workflows-0.64.2 → django_forms_workflows-0.65.1}/django_forms_workflows/form_builder_views.py +2 -1
- {django_forms_workflows-0.64.2 → django_forms_workflows-0.65.1}/django_forms_workflows/management/commands/seed_farm_demo.py +1 -0
- django_forms_workflows-0.65.1/django_forms_workflows/migrations/0090_alter_stageapprovalgroup_options_and_more.py +44 -0
- {django_forms_workflows-0.64.2 → django_forms_workflows-0.65.1}/django_forms_workflows/models.py +71 -3
- {django_forms_workflows-0.64.2 → django_forms_workflows-0.65.1}/django_forms_workflows/sync_api.py +33 -9
- {django_forms_workflows-0.64.2 → django_forms_workflows-0.65.1}/django_forms_workflows/views.py +9 -9
- {django_forms_workflows-0.64.2 → django_forms_workflows-0.65.1}/django_forms_workflows/workflow_builder_views.py +8 -2
- {django_forms_workflows-0.64.2 → django_forms_workflows-0.65.1}/django_forms_workflows/workflow_engine.py +6 -4
- {django_forms_workflows-0.64.2 → django_forms_workflows-0.65.1}/pyproject.toml +1 -1
- {django_forms_workflows-0.64.2 → django_forms_workflows-0.65.1}/CHANGELOG.md +0 -0
- {django_forms_workflows-0.64.2 → django_forms_workflows-0.65.1}/LICENSE +0 -0
- {django_forms_workflows-0.64.2 → django_forms_workflows-0.65.1}/README.md +0 -0
- {django_forms_workflows-0.64.2 → django_forms_workflows-0.65.1}/django_forms_workflows/__init__.py +0 -0
- {django_forms_workflows-0.64.2 → django_forms_workflows-0.65.1}/django_forms_workflows/api_urls.py +0 -0
- {django_forms_workflows-0.64.2 → django_forms_workflows-0.65.1}/django_forms_workflows/api_views.py +0 -0
- {django_forms_workflows-0.64.2 → django_forms_workflows-0.65.1}/django_forms_workflows/apps.py +0 -0
- {django_forms_workflows-0.64.2 → django_forms_workflows-0.65.1}/django_forms_workflows/callback_registry.py +0 -0
- {django_forms_workflows-0.64.2 → django_forms_workflows-0.65.1}/django_forms_workflows/conditions.py +0 -0
- {django_forms_workflows-0.64.2 → django_forms_workflows-0.65.1}/django_forms_workflows/context_processors.py +0 -0
- {django_forms_workflows-0.64.2 → django_forms_workflows-0.65.1}/django_forms_workflows/data_sources/__init__.py +0 -0
- {django_forms_workflows-0.64.2 → django_forms_workflows-0.65.1}/django_forms_workflows/data_sources/base.py +0 -0
- {django_forms_workflows-0.64.2 → django_forms_workflows-0.65.1}/django_forms_workflows/data_sources/database_source.py +0 -0
- {django_forms_workflows-0.64.2 → django_forms_workflows-0.65.1}/django_forms_workflows/data_sources/ldap_source.py +0 -0
- {django_forms_workflows-0.64.2 → django_forms_workflows-0.65.1}/django_forms_workflows/data_sources/user_source.py +0 -0
- {django_forms_workflows-0.64.2 → django_forms_workflows-0.65.1}/django_forms_workflows/diff_views.py +0 -0
- {django_forms_workflows-0.64.2 → django_forms_workflows-0.65.1}/django_forms_workflows/email_backends/__init__.py +0 -0
- {django_forms_workflows-0.64.2 → django_forms_workflows-0.65.1}/django_forms_workflows/email_backends/gmail_api.py +0 -0
- {django_forms_workflows-0.64.2 → django_forms_workflows-0.65.1}/django_forms_workflows/form_builder_urls.py +0 -0
- {django_forms_workflows-0.64.2 → django_forms_workflows-0.65.1}/django_forms_workflows/forms.py +0 -0
- {django_forms_workflows-0.64.2 → django_forms_workflows-0.65.1}/django_forms_workflows/handlers/__init__.py +0 -0
- {django_forms_workflows-0.64.2 → django_forms_workflows-0.65.1}/django_forms_workflows/handlers/api_handler.py +0 -0
- {django_forms_workflows-0.64.2 → django_forms_workflows-0.65.1}/django_forms_workflows/handlers/base.py +0 -0
- {django_forms_workflows-0.64.2 → django_forms_workflows-0.65.1}/django_forms_workflows/handlers/database_handler.py +0 -0
- {django_forms_workflows-0.64.2 → django_forms_workflows-0.65.1}/django_forms_workflows/handlers/email_handler.py +0 -0
- {django_forms_workflows-0.64.2 → django_forms_workflows-0.65.1}/django_forms_workflows/handlers/executor.py +0 -0
- {django_forms_workflows-0.64.2 → django_forms_workflows-0.65.1}/django_forms_workflows/handlers/file_handler.py +0 -0
- {django_forms_workflows-0.64.2 → django_forms_workflows-0.65.1}/django_forms_workflows/handlers/ldap_handler.py +0 -0
- {django_forms_workflows-0.64.2 → django_forms_workflows-0.65.1}/django_forms_workflows/history.py +0 -0
- {django_forms_workflows-0.64.2 → django_forms_workflows-0.65.1}/django_forms_workflows/ldap_backend.py +0 -0
- {django_forms_workflows-0.64.2 → django_forms_workflows-0.65.1}/django_forms_workflows/management/commands/create_default_templates.py +0 -0
- {django_forms_workflows-0.64.2 → django_forms_workflows-0.65.1}/django_forms_workflows/management/commands/pull_forms.py +0 -0
- {django_forms_workflows-0.64.2 → django_forms_workflows-0.65.1}/django_forms_workflows/management/commands/push_forms.py +0 -0
- {django_forms_workflows-0.64.2 → django_forms_workflows-0.65.1}/django_forms_workflows/management/commands/seed_pcn_form.py +0 -0
- {django_forms_workflows-0.64.2 → django_forms_workflows-0.65.1}/django_forms_workflows/management/commands/seed_prefill_sources.py +0 -0
- {django_forms_workflows-0.64.2 → django_forms_workflows-0.65.1}/django_forms_workflows/management/commands/sync_ldap_profiles.py +0 -0
- {django_forms_workflows-0.64.2 → django_forms_workflows-0.65.1}/django_forms_workflows/management/commands/sync_ldap_users.py +0 -0
- {django_forms_workflows-0.64.2 → django_forms_workflows-0.65.1}/django_forms_workflows/management/commands/test_db_connection.py +0 -0
- {django_forms_workflows-0.64.2 → django_forms_workflows-0.65.1}/django_forms_workflows/migrations/0001_initial.py +0 -0
- {django_forms_workflows-0.64.2 → django_forms_workflows-0.65.1}/django_forms_workflows/migrations/0002_prefillsource_alter_formfield_prefill_source_and_more.py +0 -0
- {django_forms_workflows-0.64.2 → django_forms_workflows-0.65.1}/django_forms_workflows/migrations/0003_postsubmissionaction.py +0 -0
- {django_forms_workflows-0.64.2 → django_forms_workflows-0.65.1}/django_forms_workflows/migrations/0004_formtemplate.py +0 -0
- {django_forms_workflows-0.64.2 → django_forms_workflows-0.65.1}/django_forms_workflows/migrations/0005_advanced_conditional_logic.py +0 -0
- {django_forms_workflows-0.64.2 → django_forms_workflows-0.65.1}/django_forms_workflows/migrations/0006_workflowdefinition_visual_workflow_data_and_more.py +0 -0
- {django_forms_workflows-0.64.2 → django_forms_workflows-0.65.1}/django_forms_workflows/migrations/0007_add_userprofile_ldap_enhancements.py +0 -0
- {django_forms_workflows-0.64.2 → django_forms_workflows-0.65.1}/django_forms_workflows/migrations/0008_add_file_workflow_models.py +0 -0
- {django_forms_workflows-0.64.2 → django_forms_workflows-0.65.1}/django_forms_workflows/migrations/0009_add_formfield_readonly.py +0 -0
- {django_forms_workflows-0.64.2 → django_forms_workflows-0.65.1}/django_forms_workflows/migrations/0010_add_prefillsource_template_fields.py +0 -0
- {django_forms_workflows-0.64.2 → django_forms_workflows-0.65.1}/django_forms_workflows/migrations/0011_postsubmissionaction_email_body_template_and_more.py +0 -0
- {django_forms_workflows-0.64.2 → django_forms_workflows-0.65.1}/django_forms_workflows/migrations/0012_add_approval_step_fields.py +0 -0
- {django_forms_workflows-0.64.2 → django_forms_workflows-0.65.1}/django_forms_workflows/migrations/0013_add_database_query_key.py +0 -0
- {django_forms_workflows-0.64.2 → django_forms_workflows-0.65.1}/django_forms_workflows/migrations/0014_add_form_category.py +0 -0
- {django_forms_workflows-0.64.2 → django_forms_workflows-0.65.1}/django_forms_workflows/migrations/0015_add_workflowstage_staged_approvals.py +0 -0
- {django_forms_workflows-0.64.2 → django_forms_workflows-0.65.1}/django_forms_workflows/migrations/0016_add_pdf_generation.py +0 -0
- {django_forms_workflows-0.64.2 → django_forms_workflows-0.65.1}/django_forms_workflows/migrations/0017_add_notification_batching.py +0 -0
- {django_forms_workflows-0.64.2 → django_forms_workflows-0.65.1}/django_forms_workflows/migrations/0018_add_form_category_parent.py +0 -0
- {django_forms_workflows-0.64.2 → django_forms_workflows-0.65.1}/django_forms_workflows/migrations/0019_add_ldap_group_profile.py +0 -0
- {django_forms_workflows-0.64.2 → django_forms_workflows-0.65.1}/django_forms_workflows/migrations/0020_add_bulk_export_field.py +0 -0
- {django_forms_workflows-0.64.2 → django_forms_workflows-0.65.1}/django_forms_workflows/migrations/0021_alter_pendingnotification_scheduled_for_and_more.py +0 -0
- {django_forms_workflows-0.64.2 → django_forms_workflows-0.65.1}/django_forms_workflows/migrations/0022_add_bulk_pdf_export.py +0 -0
- {django_forms_workflows-0.64.2 → django_forms_workflows-0.65.1}/django_forms_workflows/migrations/0023_add_performance_indexes.py +0 -0
- {django_forms_workflows-0.64.2 → django_forms_workflows-0.65.1}/django_forms_workflows/migrations/0024_add_allow_resubmit.py +0 -0
- {django_forms_workflows-0.64.2 → django_forms_workflows-0.65.1}/django_forms_workflows/migrations/0025_workflowstage_approve_label.py +0 -0
- {django_forms_workflows-0.64.2 → django_forms_workflows-0.65.1}/django_forms_workflows/migrations/0026_alter_formfield_width.py +0 -0
- {django_forms_workflows-0.64.2 → django_forms_workflows-0.65.1}/django_forms_workflows/migrations/0027_formsubmission_form_data_gin.py +0 -0
- {django_forms_workflows-0.64.2 → django_forms_workflows-0.65.1}/django_forms_workflows/migrations/0028_workflowstagegroupconfig.py +0 -0
- {django_forms_workflows-0.64.2 → django_forms_workflows-0.65.1}/django_forms_workflows/migrations/0029_formfield_workflow_stage_fk_drop_groupconfig.py +0 -0
- {django_forms_workflows-0.64.2 → django_forms_workflows-0.65.1}/django_forms_workflows/migrations/0030_formfield_phone_type.py +0 -0
- {django_forms_workflows-0.64.2 → django_forms_workflows-0.65.1}/django_forms_workflows/migrations/0031_sub_workflows.py +0 -0
- {django_forms_workflows-0.64.2 → django_forms_workflows-0.65.1}/django_forms_workflows/migrations/0032_approved_pending_detached_sub_workflow.py +0 -0
- {django_forms_workflows-0.64.2 → django_forms_workflows-0.65.1}/django_forms_workflows/migrations/0033_add_reject_parent_to_subworkflowdefinition.py +0 -0
- {django_forms_workflows-0.64.2 → django_forms_workflows-0.65.1}/django_forms_workflows/migrations/0034_add_notificationlog.py +0 -0
- {django_forms_workflows-0.64.2 → django_forms_workflows-0.65.1}/django_forms_workflows/migrations/0035_migrate_prefill_source_strings.py +0 -0
- {django_forms_workflows-0.64.2 → django_forms_workflows-0.65.1}/django_forms_workflows/migrations/0036_add_workflowstage_auto_created.py +0 -0
- {django_forms_workflows-0.64.2 → django_forms_workflows-0.65.1}/django_forms_workflows/migrations/0037_migrate_flat_workflows_to_staged.py +0 -0
- {django_forms_workflows-0.64.2 → django_forms_workflows-0.65.1}/django_forms_workflows/migrations/0038_remove_legacy_prefill_source_and_approval_step.py +0 -0
- {django_forms_workflows-0.64.2 → django_forms_workflows-0.65.1}/django_forms_workflows/migrations/0039_update_help_text.py +0 -0
- {django_forms_workflows-0.64.2 → django_forms_workflows-0.65.1}/django_forms_workflows/migrations/0040_migrate_deprecated_features.py +0 -0
- {django_forms_workflows-0.64.2 → django_forms_workflows-0.65.1}/django_forms_workflows/migrations/0041_remove_deprecated_fields.py +0 -0
- {django_forms_workflows-0.64.2 → django_forms_workflows-0.65.1}/django_forms_workflows/migrations/0042_add_sub_workflow_section_label.py +0 -0
- {django_forms_workflows-0.64.2 → django_forms_workflows-0.65.1}/django_forms_workflows/migrations/0043_fix_form_data_decimal_encoding.py +0 -0
- {django_forms_workflows-0.64.2 → django_forms_workflows-0.65.1}/django_forms_workflows/migrations/0044_remove_subworkflowinstance_label.py +0 -0
- {django_forms_workflows-0.64.2 → django_forms_workflows-0.65.1}/django_forms_workflows/migrations/0045_stageapprovalgroup_workflow_name_label.py +0 -0
- {django_forms_workflows-0.64.2 → django_forms_workflows-0.65.1}/django_forms_workflows/migrations/0046_workflow_definition_one_to_many.py +0 -0
- {django_forms_workflows-0.64.2 → django_forms_workflows-0.65.1}/django_forms_workflows/migrations/0047_add_hide_approval_history.py +0 -0
- {django_forms_workflows-0.64.2 → django_forms_workflows-0.65.1}/django_forms_workflows/migrations/0048_workflowdefinition_trigger_conditions_and_more.py +0 -0
- {django_forms_workflows-0.64.2 → django_forms_workflows-0.65.1}/django_forms_workflows/migrations/0049_formfield_multifile_type.py +0 -0
- {django_forms_workflows-0.64.2 → django_forms_workflows-0.65.1}/django_forms_workflows/migrations/0050_workflowdefinition_collapse_parallel_stages.py +0 -0
- {django_forms_workflows-0.64.2 → django_forms_workflows-0.65.1}/django_forms_workflows/migrations/0051_formdefinition_is_listed.py +0 -0
- {django_forms_workflows-0.64.2 → django_forms_workflows-0.65.1}/django_forms_workflows/migrations/0052_dynamic_assignee_and_form_field_notifications.py +0 -0
- {django_forms_workflows-0.64.2 → django_forms_workflows-0.65.1}/django_forms_workflows/migrations/0053_stageformfieldnotification_static_emails.py +0 -0
- {django_forms_workflows-0.64.2 → django_forms_workflows-0.65.1}/django_forms_workflows/migrations/0054_rename_approved_pending_to_pending_approval.py +0 -0
- {django_forms_workflows-0.64.2 → django_forms_workflows-0.65.1}/django_forms_workflows/migrations/0055_add_send_back.py +0 -0
- {django_forms_workflows-0.64.2 → django_forms_workflows-0.65.1}/django_forms_workflows/migrations/0056_calculated_formula_spreadsheet.py +0 -0
- {django_forms_workflows-0.64.2 → django_forms_workflows-0.65.1}/django_forms_workflows/migrations/0057_add_currency_field_type.py +0 -0
- {django_forms_workflows-0.64.2 → django_forms_workflows-0.65.1}/django_forms_workflows/migrations/0058_rename_assignee_email_field_add_lookup_type.py +0 -0
- {django_forms_workflows-0.64.2 → django_forms_workflows-0.65.1}/django_forms_workflows/migrations/0059_add_multiselect_list_field_type.py +0 -0
- {django_forms_workflows-0.64.2 → django_forms_workflows-0.65.1}/django_forms_workflows/migrations/0060_alter_workflowstage_assignee_lookup_type_helptext.py +0 -0
- {django_forms_workflows-0.64.2 → django_forms_workflows-0.65.1}/django_forms_workflows/migrations/0061_add_country_us_state_field_types.py +0 -0
- {django_forms_workflows-0.64.2 → django_forms_workflows-0.65.1}/django_forms_workflows/migrations/0062_add_batch_import_to_formdefinition.py +0 -0
- {django_forms_workflows-0.64.2 → django_forms_workflows-0.65.1}/django_forms_workflows/migrations/0063_formdefinition_api_enabled_apitoken.py +0 -0
- {django_forms_workflows-0.64.2 → django_forms_workflows-0.65.1}/django_forms_workflows/migrations/0064_add_reviewer_groups.py +0 -0
- {django_forms_workflows-0.64.2 → django_forms_workflows-0.65.1}/django_forms_workflows/migrations/0065_workflownotification.py +0 -0
- {django_forms_workflows-0.64.2 → django_forms_workflows-0.65.1}/django_forms_workflows/migrations/0066_add_notify_submitter_to_workflownotification.py +0 -0
- {django_forms_workflows-0.64.2 → django_forms_workflows-0.65.1}/django_forms_workflows/migrations/0067_migrate_legacy_notify_flags.py +0 -0
- {django_forms_workflows-0.64.2 → django_forms_workflows-0.65.1}/django_forms_workflows/migrations/0068_drop_legacy_notify_fields.py +0 -0
- {django_forms_workflows-0.64.2 → django_forms_workflows-0.65.1}/django_forms_workflows/migrations/0069_add_signature_field_type.py +0 -0
- {django_forms_workflows-0.64.2 → django_forms_workflows-0.65.1}/django_forms_workflows/migrations/0070_workflowstage_allow_edit_form_data.py +0 -0
- {django_forms_workflows-0.64.2 → django_forms_workflows-0.65.1}/django_forms_workflows/migrations/0071_alter_pendingnotification_notification_type.py +0 -0
- {django_forms_workflows-0.64.2 → django_forms_workflows-0.65.1}/django_forms_workflows/migrations/0072_add_change_history.py +0 -0
- {django_forms_workflows-0.64.2 → django_forms_workflows-0.65.1}/django_forms_workflows/migrations/0073_add_stage_notify_assignee_on_final_decision.py +0 -0
- {django_forms_workflows-0.64.2 → django_forms_workflows-0.65.1}/django_forms_workflows/migrations/0074_add_notification_rule.py +0 -0
- {django_forms_workflows-0.64.2 → django_forms_workflows-0.65.1}/django_forms_workflows/migrations/0075_migrate_to_notification_rules.py +0 -0
- {django_forms_workflows-0.64.2 → django_forms_workflows-0.65.1}/django_forms_workflows/migrations/0076_update_notification_event_choices.py +0 -0
- {django_forms_workflows-0.64.2 → django_forms_workflows-0.65.1}/django_forms_workflows/migrations/0077_drop_legacy_notification_models.py +0 -0
- {django_forms_workflows-0.64.2 → django_forms_workflows-0.65.1}/django_forms_workflows/migrations/0078_allow_anonymous_submissions.py +0 -0
- {django_forms_workflows-0.64.2 → django_forms_workflows-0.65.1}/django_forms_workflows/migrations/0079_webhookendpoint_webhookdeliverylog.py +0 -0
- {django_forms_workflows-0.64.2 → django_forms_workflows-0.65.1}/django_forms_workflows/migrations/0080_add_rating_matrix_address_slider_fields_and_form_controls.py +0 -0
- {django_forms_workflows-0.64.2 → django_forms_workflows-0.65.1}/django_forms_workflows/migrations/0081_add_success_page_fields.py +0 -0
- {django_forms_workflows-0.64.2 → django_forms_workflows-0.65.1}/django_forms_workflows/migrations/0082_add_document_template_model.py +0 -0
- {django_forms_workflows-0.64.2 → django_forms_workflows-0.65.1}/django_forms_workflows/migrations/0083_workflowdefinition_start_trigger.py +0 -0
- {django_forms_workflows-0.64.2 → django_forms_workflows-0.65.1}/django_forms_workflows/migrations/0084_add_shared_option_list.py +0 -0
- {django_forms_workflows-0.64.2 → django_forms_workflows-0.65.1}/django_forms_workflows/migrations/0085_add_payment_system.py +0 -0
- {django_forms_workflows-0.64.2 → django_forms_workflows-0.65.1}/django_forms_workflows/migrations/0086_add_embed_enabled.py +0 -0
- {django_forms_workflows-0.64.2 → django_forms_workflows-0.65.1}/django_forms_workflows/migrations/0087_notificationrule_use_triggering_stage.py +0 -0
- {django_forms_workflows-0.64.2 → django_forms_workflows-0.65.1}/django_forms_workflows/migrations/0088_notificationrule_body_template_and_events.py +0 -0
- {django_forms_workflows-0.64.2 → django_forms_workflows-0.65.1}/django_forms_workflows/migrations/0089_workflowstage_hide_comment_field.py +0 -0
- {django_forms_workflows-0.64.2 → django_forms_workflows-0.65.1}/django_forms_workflows/migrations/__init__.py +0 -0
- {django_forms_workflows-0.64.2 → django_forms_workflows-0.65.1}/django_forms_workflows/payments/__init__.py +0 -0
- {django_forms_workflows-0.64.2 → django_forms_workflows-0.65.1}/django_forms_workflows/payments/base.py +0 -0
- {django_forms_workflows-0.64.2 → django_forms_workflows-0.65.1}/django_forms_workflows/payments/registry.py +0 -0
- {django_forms_workflows-0.64.2 → django_forms_workflows-0.65.1}/django_forms_workflows/payments/stripe_provider.py +0 -0
- {django_forms_workflows-0.64.2 → django_forms_workflows-0.65.1}/django_forms_workflows/payments/views.py +0 -0
- {django_forms_workflows-0.64.2 → django_forms_workflows-0.65.1}/django_forms_workflows/reporting_views.py +0 -0
- {django_forms_workflows-0.64.2 → django_forms_workflows-0.65.1}/django_forms_workflows/signals.py +0 -0
- {django_forms_workflows-0.64.2 → django_forms_workflows-0.65.1}/django_forms_workflows/sso_backends.py +0 -0
- {django_forms_workflows-0.64.2 → django_forms_workflows-0.65.1}/django_forms_workflows/sso_urls.py +0 -0
- {django_forms_workflows-0.64.2 → django_forms_workflows-0.65.1}/django_forms_workflows/sso_views.py +0 -0
- {django_forms_workflows-0.64.2 → django_forms_workflows-0.65.1}/django_forms_workflows/static/django_forms_workflows/api/swagger-ui-bundle.js +0 -0
- {django_forms_workflows-0.64.2 → django_forms_workflows-0.65.1}/django_forms_workflows/static/django_forms_workflows/api/swagger-ui.css +0 -0
- {django_forms_workflows-0.64.2 → django_forms_workflows-0.65.1}/django_forms_workflows/static/django_forms_workflows/css/forms.css +0 -0
- {django_forms_workflows-0.64.2 → django_forms_workflows-0.65.1}/django_forms_workflows/static/django_forms_workflows/js/dfw-embed.js +0 -0
- {django_forms_workflows-0.64.2 → django_forms_workflows-0.65.1}/django_forms_workflows/static/django_forms_workflows/js/form-builder.js +0 -0
- {django_forms_workflows-0.64.2 → django_forms_workflows-0.65.1}/django_forms_workflows/static/django_forms_workflows/js/form-enhancements.js +0 -0
- {django_forms_workflows-0.64.2 → django_forms_workflows-0.65.1}/django_forms_workflows/static/django_forms_workflows/js/payment-stripe.js +0 -0
- {django_forms_workflows-0.64.2 → django_forms_workflows-0.65.1}/django_forms_workflows/static/django_forms_workflows/js/signature-pad.js +0 -0
- {django_forms_workflows-0.64.2 → django_forms_workflows-0.65.1}/django_forms_workflows/static/django_forms_workflows/js/workflow-builder.js +0 -0
- {django_forms_workflows-0.64.2 → django_forms_workflows-0.65.1}/django_forms_workflows/sync_views.py +0 -0
- {django_forms_workflows-0.64.2 → django_forms_workflows-0.65.1}/django_forms_workflows/tasks.py +0 -0
- {django_forms_workflows-0.64.2 → django_forms_workflows-0.65.1}/django_forms_workflows/templates/admin/django_forms_workflows/_sync_diff.html +0 -0
- {django_forms_workflows-0.64.2 → django_forms_workflows-0.65.1}/django_forms_workflows/templates/admin/django_forms_workflows/diff_forms.html +0 -0
- {django_forms_workflows-0.64.2 → django_forms_workflows-0.65.1}/django_forms_workflows/templates/admin/django_forms_workflows/form_builder.html +0 -0
- {django_forms_workflows-0.64.2 → django_forms_workflows-0.65.1}/django_forms_workflows/templates/admin/django_forms_workflows/formdef_change_form.html +0 -0
- {django_forms_workflows-0.64.2 → django_forms_workflows-0.65.1}/django_forms_workflows/templates/admin/django_forms_workflows/formdefinition/change_list.html +0 -0
- {django_forms_workflows-0.64.2 → django_forms_workflows-0.65.1}/django_forms_workflows/templates/admin/django_forms_workflows/sync_import.html +0 -0
- {django_forms_workflows-0.64.2 → django_forms_workflows-0.65.1}/django_forms_workflows/templates/admin/django_forms_workflows/sync_pull.html +0 -0
- {django_forms_workflows-0.64.2 → django_forms_workflows-0.65.1}/django_forms_workflows/templates/admin/django_forms_workflows/sync_push.html +0 -0
- {django_forms_workflows-0.64.2 → django_forms_workflows-0.65.1}/django_forms_workflows/templates/admin/django_forms_workflows/workflow_builder.html +0 -0
- {django_forms_workflows-0.64.2 → django_forms_workflows-0.65.1}/django_forms_workflows/templates/django_forms_workflows/_category_node.html +0 -0
- {django_forms_workflows-0.64.2 → django_forms_workflows-0.65.1}/django_forms_workflows/templates/django_forms_workflows/_field_value.html +0 -0
- {django_forms_workflows-0.64.2 → django_forms_workflows-0.65.1}/django_forms_workflows/templates/django_forms_workflows/_form_data_rows.html +0 -0
- {django_forms_workflows-0.64.2 → django_forms_workflows-0.65.1}/django_forms_workflows/templates/django_forms_workflows/analytics_dashboard.html +0 -0
- {django_forms_workflows-0.64.2 → django_forms_workflows-0.65.1}/django_forms_workflows/templates/django_forms_workflows/api/docs.html +0 -0
- {django_forms_workflows-0.64.2 → django_forms_workflows-0.65.1}/django_forms_workflows/templates/django_forms_workflows/approval_inbox.html +0 -0
- {django_forms_workflows-0.64.2 → django_forms_workflows-0.65.1}/django_forms_workflows/templates/django_forms_workflows/approve.html +0 -0
- {django_forms_workflows-0.64.2 → django_forms_workflows-0.65.1}/django_forms_workflows/templates/django_forms_workflows/base.html +0 -0
- {django_forms_workflows-0.64.2 → django_forms_workflows-0.65.1}/django_forms_workflows/templates/django_forms_workflows/batch_import_result.html +0 -0
- {django_forms_workflows-0.64.2 → django_forms_workflows-0.65.1}/django_forms_workflows/templates/django_forms_workflows/completed_approvals.html +0 -0
- {django_forms_workflows-0.64.2 → django_forms_workflows-0.65.1}/django_forms_workflows/templates/django_forms_workflows/discard_draft_confirm.html +0 -0
- {django_forms_workflows-0.64.2 → django_forms_workflows-0.65.1}/django_forms_workflows/templates/django_forms_workflows/embed_base.html +0 -0
- {django_forms_workflows-0.64.2 → django_forms_workflows-0.65.1}/django_forms_workflows/templates/django_forms_workflows/embed_success.html +0 -0
- {django_forms_workflows-0.64.2 → django_forms_workflows-0.65.1}/django_forms_workflows/templates/django_forms_workflows/form_categories.html +0 -0
- {django_forms_workflows-0.64.2 → django_forms_workflows-0.65.1}/django_forms_workflows/templates/django_forms_workflows/form_embed.html +0 -0
- {django_forms_workflows-0.64.2 → django_forms_workflows-0.65.1}/django_forms_workflows/templates/django_forms_workflows/form_list.html +0 -0
- {django_forms_workflows-0.64.2 → django_forms_workflows-0.65.1}/django_forms_workflows/templates/django_forms_workflows/form_submit.html +0 -0
- {django_forms_workflows-0.64.2 → django_forms_workflows-0.65.1}/django_forms_workflows/templates/django_forms_workflows/my_submissions.html +0 -0
- {django_forms_workflows-0.64.2 → django_forms_workflows-0.65.1}/django_forms_workflows/templates/django_forms_workflows/payment_collect.html +0 -0
- {django_forms_workflows-0.64.2 → django_forms_workflows-0.65.1}/django_forms_workflows/templates/django_forms_workflows/payment_error.html +0 -0
- {django_forms_workflows-0.64.2 → django_forms_workflows-0.65.1}/django_forms_workflows/templates/django_forms_workflows/public_submission_confirmation.html +0 -0
- {django_forms_workflows-0.64.2 → django_forms_workflows-0.65.1}/django_forms_workflows/templates/django_forms_workflows/rate_limited.html +0 -0
- {django_forms_workflows-0.64.2 → django_forms_workflows-0.65.1}/django_forms_workflows/templates/django_forms_workflows/reassign_task.html +0 -0
- {django_forms_workflows-0.64.2 → django_forms_workflows-0.65.1}/django_forms_workflows/templates/django_forms_workflows/resubmit_confirm.html +0 -0
- {django_forms_workflows-0.64.2 → django_forms_workflows-0.65.1}/django_forms_workflows/templates/django_forms_workflows/sso/login.html +0 -0
- {django_forms_workflows-0.64.2 → django_forms_workflows-0.65.1}/django_forms_workflows/templates/django_forms_workflows/sub_workflow_detail.html +0 -0
- {django_forms_workflows-0.64.2 → django_forms_workflows-0.65.1}/django_forms_workflows/templates/django_forms_workflows/submission_bulk_pdf.html +0 -0
- {django_forms_workflows-0.64.2 → django_forms_workflows-0.65.1}/django_forms_workflows/templates/django_forms_workflows/submission_detail.html +0 -0
- {django_forms_workflows-0.64.2 → django_forms_workflows-0.65.1}/django_forms_workflows/templates/django_forms_workflows/submission_pdf.html +0 -0
- {django_forms_workflows-0.64.2 → django_forms_workflows-0.65.1}/django_forms_workflows/templates/django_forms_workflows/submission_success.html +0 -0
- {django_forms_workflows-0.64.2 → django_forms_workflows-0.65.1}/django_forms_workflows/templates/django_forms_workflows/withdraw_confirm.html +0 -0
- {django_forms_workflows-0.64.2 → django_forms_workflows-0.65.1}/django_forms_workflows/templates/emails/approval_notification.html +0 -0
- {django_forms_workflows-0.64.2 → django_forms_workflows-0.65.1}/django_forms_workflows/templates/emails/approval_reminder.html +0 -0
- {django_forms_workflows-0.64.2 → django_forms_workflows-0.65.1}/django_forms_workflows/templates/emails/approval_request.html +0 -0
- {django_forms_workflows-0.64.2 → django_forms_workflows-0.65.1}/django_forms_workflows/templates/emails/email_styles.html +0 -0
- {django_forms_workflows-0.64.2 → django_forms_workflows-0.65.1}/django_forms_workflows/templates/emails/escalation_notification.html +0 -0
- {django_forms_workflows-0.64.2 → django_forms_workflows-0.65.1}/django_forms_workflows/templates/emails/notification_digest.html +0 -0
- {django_forms_workflows-0.64.2 → django_forms_workflows-0.65.1}/django_forms_workflows/templates/emails/rejection_notification.html +0 -0
- {django_forms_workflows-0.64.2 → django_forms_workflows-0.65.1}/django_forms_workflows/templates/emails/submission_notification.html +0 -0
- {django_forms_workflows-0.64.2 → django_forms_workflows-0.65.1}/django_forms_workflows/templates/registration/login.html +0 -0
- {django_forms_workflows-0.64.2 → django_forms_workflows-0.65.1}/django_forms_workflows/templatetags/__init__.py +0 -0
- {django_forms_workflows-0.64.2 → django_forms_workflows-0.65.1}/django_forms_workflows/templatetags/forms_workflows_tags.py +0 -0
- {django_forms_workflows-0.64.2 → django_forms_workflows-0.65.1}/django_forms_workflows/urls.py +0 -0
- {django_forms_workflows-0.64.2 → django_forms_workflows-0.65.1}/django_forms_workflows/utils.py +0 -0
{django_forms_workflows-0.64.2 → django_forms_workflows-0.65.1}/django_forms_workflows/admin.py
RENAMED
|
@@ -477,8 +477,9 @@ class StageApprovalGroupInline(nested_admin.NestedTabularInline):
|
|
|
477
477
|
|
|
478
478
|
model = StageApprovalGroup
|
|
479
479
|
extra = 1
|
|
480
|
-
ordering = ("position"
|
|
480
|
+
ordering = ("role", "position")
|
|
481
481
|
autocomplete_fields = ("group",)
|
|
482
|
+
fields = ("group", "role", "position")
|
|
482
483
|
|
|
483
484
|
|
|
484
485
|
class WorkflowStageInline(nested_admin.NestedStackedInline):
|
|
@@ -963,11 +964,12 @@ class FormDefinitionAdmin(nested_admin.NestedModelAdmin):
|
|
|
963
964
|
)
|
|
964
965
|
for sag in StageApprovalGroup.objects.filter(
|
|
965
966
|
stage=stage
|
|
966
|
-
).order_by("position"):
|
|
967
|
+
).order_by("role", "position"):
|
|
967
968
|
StageApprovalGroup.objects.create(
|
|
968
969
|
stage=cloned_stage,
|
|
969
970
|
group=sag.group,
|
|
970
971
|
position=sag.position,
|
|
972
|
+
role=sag.role,
|
|
971
973
|
)
|
|
972
974
|
# Clone SubWorkflowDefinition if present
|
|
973
975
|
try:
|
|
@@ -187,12 +187,13 @@ def form_builder_clone(request, form_id):
|
|
|
187
187
|
trigger_conditions=stage.trigger_conditions,
|
|
188
188
|
)
|
|
189
189
|
for sag in StageApprovalGroup.objects.filter(stage=stage).order_by(
|
|
190
|
-
"position"
|
|
190
|
+
"role", "position"
|
|
191
191
|
):
|
|
192
192
|
StageApprovalGroup.objects.create(
|
|
193
193
|
stage=cloned_stage,
|
|
194
194
|
group=sag.group,
|
|
195
195
|
position=sag.position,
|
|
196
|
+
role=sag.role,
|
|
196
197
|
)
|
|
197
198
|
# Clone SubWorkflowDefinition if present
|
|
198
199
|
try:
|
|
@@ -0,0 +1,44 @@
|
|
|
1
|
+
# Generated by Django 5.2.7 on 2026-04-13 17:37
|
|
2
|
+
|
|
3
|
+
from django.db import migrations, models
|
|
4
|
+
|
|
5
|
+
|
|
6
|
+
class Migration(migrations.Migration):
|
|
7
|
+
|
|
8
|
+
dependencies = [
|
|
9
|
+
("auth", "0012_alter_user_first_name_max_length"),
|
|
10
|
+
("django_forms_workflows", "0089_workflowstage_hide_comment_field"),
|
|
11
|
+
]
|
|
12
|
+
|
|
13
|
+
operations = [
|
|
14
|
+
migrations.AlterModelOptions(
|
|
15
|
+
name="stageapprovalgroup",
|
|
16
|
+
options={
|
|
17
|
+
"ordering": ["role", "position"],
|
|
18
|
+
"verbose_name": "Stage Approval Group",
|
|
19
|
+
"verbose_name_plural": "Stage Approval Groups",
|
|
20
|
+
},
|
|
21
|
+
),
|
|
22
|
+
migrations.AlterUniqueTogether(
|
|
23
|
+
name="stageapprovalgroup",
|
|
24
|
+
unique_together=set(),
|
|
25
|
+
),
|
|
26
|
+
migrations.AddField(
|
|
27
|
+
model_name="stageapprovalgroup",
|
|
28
|
+
name="role",
|
|
29
|
+
field=models.CharField(
|
|
30
|
+
choices=[
|
|
31
|
+
("approval", "Approval (default)"),
|
|
32
|
+
("validation", "Assignee validation"),
|
|
33
|
+
("reassignment", "Reassignment pool"),
|
|
34
|
+
],
|
|
35
|
+
default="approval",
|
|
36
|
+
help_text="Purpose of this group in the stage. 'Approval' groups receive fallback tasks and define the default pool. 'Validation' groups are checked when verifying a dynamic assignee's group membership (falls back to approval groups when none defined). 'Reassignment' groups define who may be reassigned to (falls back to approval groups when none defined).",
|
|
37
|
+
max_length=20,
|
|
38
|
+
),
|
|
39
|
+
),
|
|
40
|
+
migrations.AlterUniqueTogether(
|
|
41
|
+
name="stageapprovalgroup",
|
|
42
|
+
unique_together={("stage", "group", "role")},
|
|
43
|
+
),
|
|
44
|
+
]
|
{django_forms_workflows-0.64.2 → django_forms_workflows-0.65.1}/django_forms_workflows/models.py
RENAMED
|
@@ -1249,6 +1249,39 @@ class WorkflowStage(models.Model):
|
|
|
1249
1249
|
def __str__(self) -> str:
|
|
1250
1250
|
return f"Stage {self.order}: {self.name}"
|
|
1251
1251
|
|
|
1252
|
+
# ------------------------------------------------------------------
|
|
1253
|
+
# Helpers to retrieve groups by role (with fallback to approval)
|
|
1254
|
+
# ------------------------------------------------------------------
|
|
1255
|
+
|
|
1256
|
+
def _groups_by_role(self, role: str):
|
|
1257
|
+
"""Return groups for *role*, falling back to approval groups if none."""
|
|
1258
|
+
qs = Group.objects.filter(
|
|
1259
|
+
stageapprovalgroup__stage=self,
|
|
1260
|
+
stageapprovalgroup__role=role,
|
|
1261
|
+
).order_by("stageapprovalgroup__position")
|
|
1262
|
+
if qs.exists():
|
|
1263
|
+
return qs
|
|
1264
|
+
# Fallback: approval groups
|
|
1265
|
+
return Group.objects.filter(
|
|
1266
|
+
stageapprovalgroup__stage=self,
|
|
1267
|
+
stageapprovalgroup__role="approval",
|
|
1268
|
+
).order_by("stageapprovalgroup__position")
|
|
1269
|
+
|
|
1270
|
+
def get_validation_groups(self):
|
|
1271
|
+
"""Groups used to validate a dynamic assignee's membership."""
|
|
1272
|
+
return self._groups_by_role("validation")
|
|
1273
|
+
|
|
1274
|
+
def get_reassignment_groups(self):
|
|
1275
|
+
"""Groups that define the eligible reassignment pool."""
|
|
1276
|
+
return self._groups_by_role("reassignment")
|
|
1277
|
+
|
|
1278
|
+
def get_approval_groups(self):
|
|
1279
|
+
"""Groups used for fallback task assignment / approval logic."""
|
|
1280
|
+
return Group.objects.filter(
|
|
1281
|
+
stageapprovalgroup__stage=self,
|
|
1282
|
+
stageapprovalgroup__role="approval",
|
|
1283
|
+
).order_by("stageapprovalgroup__position")
|
|
1284
|
+
|
|
1252
1285
|
|
|
1253
1286
|
class StageApprovalGroup(models.Model):
|
|
1254
1287
|
"""
|
|
@@ -1256,8 +1289,28 @@ class StageApprovalGroup(models.Model):
|
|
|
1256
1289
|
|
|
1257
1290
|
Stores a ``position`` so admins can control the order groups are
|
|
1258
1291
|
processed when approval_logic is ``"sequence"``.
|
|
1292
|
+
|
|
1293
|
+
The ``role`` field distinguishes the purpose of a group within the stage:
|
|
1294
|
+
|
|
1295
|
+
* **approval** – the default pool used for fallback task assignment and
|
|
1296
|
+
approval logic (AND/OR/sequence).
|
|
1297
|
+
* **validation** – used to check that a dynamically resolved assignee
|
|
1298
|
+
belongs to an allowed group. When no validation groups are configured,
|
|
1299
|
+
approval groups are used instead.
|
|
1300
|
+
* **reassignment** – defines the eligible pool of users for task
|
|
1301
|
+
reassignment. When no reassignment groups are configured, approval
|
|
1302
|
+
groups are used instead.
|
|
1303
|
+
|
|
1304
|
+
The same Django ``Group`` may appear under multiple roles for a single
|
|
1305
|
+
stage (e.g. both approval and reassignment).
|
|
1259
1306
|
"""
|
|
1260
1307
|
|
|
1308
|
+
ROLE_CHOICES = [
|
|
1309
|
+
("approval", "Approval (default)"),
|
|
1310
|
+
("validation", "Assignee validation"),
|
|
1311
|
+
("reassignment", "Reassignment pool"),
|
|
1312
|
+
]
|
|
1313
|
+
|
|
1261
1314
|
stage = models.ForeignKey(
|
|
1262
1315
|
WorkflowStage,
|
|
1263
1316
|
on_delete=models.CASCADE,
|
|
@@ -1270,15 +1323,30 @@ class StageApprovalGroup(models.Model):
|
|
|
1270
1323
|
default=0,
|
|
1271
1324
|
help_text="Order in which this group is processed (lower = first)",
|
|
1272
1325
|
)
|
|
1326
|
+
role = models.CharField(
|
|
1327
|
+
max_length=20,
|
|
1328
|
+
choices=ROLE_CHOICES,
|
|
1329
|
+
default="approval",
|
|
1330
|
+
help_text=(
|
|
1331
|
+
"Purpose of this group in the stage. "
|
|
1332
|
+
"'Approval' groups receive fallback tasks and define the default pool. "
|
|
1333
|
+
"'Validation' groups are checked when verifying a dynamic assignee's "
|
|
1334
|
+
"group membership (falls back to approval groups when none defined). "
|
|
1335
|
+
"'Reassignment' groups define who may be reassigned to "
|
|
1336
|
+
"(falls back to approval groups when none defined)."
|
|
1337
|
+
),
|
|
1338
|
+
)
|
|
1273
1339
|
|
|
1274
1340
|
class Meta:
|
|
1275
|
-
ordering = ["position"]
|
|
1276
|
-
unique_together = [("stage", "group")]
|
|
1341
|
+
ordering = ["role", "position"]
|
|
1342
|
+
unique_together = [("stage", "group", "role")]
|
|
1277
1343
|
verbose_name = "Stage Approval Group"
|
|
1278
1344
|
verbose_name_plural = "Stage Approval Groups"
|
|
1279
1345
|
|
|
1280
1346
|
def __str__(self) -> str:
|
|
1281
|
-
|
|
1347
|
+
label = self.get_role_display() if self.role != "approval" else ""
|
|
1348
|
+
suffix = f" [{label}]" if label else ""
|
|
1349
|
+
return f"{self.group.name} (pos {self.position}){suffix}"
|
|
1282
1350
|
|
|
1283
1351
|
|
|
1284
1352
|
class NotificationRule(models.Model):
|
{django_forms_workflows-0.64.2 → django_forms_workflows-0.65.1}/django_forms_workflows/sync_api.py
RENAMED
|
@@ -196,7 +196,10 @@ def _serialize_category(cat):
|
|
|
196
196
|
}
|
|
197
197
|
|
|
198
198
|
|
|
199
|
-
def _serialize_field(field):
|
|
199
|
+
def _serialize_field(field, wf_pk_to_index=None):
|
|
200
|
+
wf_index = None
|
|
201
|
+
if field.workflow_stage_id and wf_pk_to_index:
|
|
202
|
+
wf_index = wf_pk_to_index.get(field.workflow_stage.workflow_id)
|
|
200
203
|
return {
|
|
201
204
|
"field_name": field.field_name,
|
|
202
205
|
"field_label": field.field_label,
|
|
@@ -230,6 +233,7 @@ def _serialize_field(field):
|
|
|
230
233
|
"workflow_stage_order": field.workflow_stage.order
|
|
231
234
|
if field.workflow_stage_id
|
|
232
235
|
else None,
|
|
236
|
+
"workflow_index": wf_index,
|
|
233
237
|
}
|
|
234
238
|
|
|
235
239
|
|
|
@@ -237,9 +241,9 @@ def _serialize_workflow_stage(stage):
|
|
|
237
241
|
# Serialize approval groups with their sequence position so that
|
|
238
242
|
# "sequence" stages are restored in the correct order on import.
|
|
239
243
|
approval_groups = [
|
|
240
|
-
{"name": sag.group.name, "position": sag.position}
|
|
244
|
+
{"name": sag.group.name, "position": sag.position, "role": sag.role}
|
|
241
245
|
for sag in stage.stageapprovalgroup_set.select_related("group").order_by(
|
|
242
|
-
"position"
|
|
246
|
+
"role", "position"
|
|
243
247
|
)
|
|
244
248
|
]
|
|
245
249
|
return {
|
|
@@ -415,6 +419,10 @@ def serialize_form(form_definition):
|
|
|
415
419
|
# Additional workflows (new: stored in "additional_workflows")
|
|
416
420
|
extra_workflows = all_workflows[1:] if len(all_workflows) > 1 else []
|
|
417
421
|
|
|
422
|
+
# Build a map from workflow PK → index so fields can record which
|
|
423
|
+
# workflow their stage belongs to (needed for multi-workflow forms).
|
|
424
|
+
wf_pk_to_index = {wf.pk: idx for idx, wf in enumerate(all_workflows)}
|
|
425
|
+
|
|
418
426
|
result = {
|
|
419
427
|
"schema_version": SYNC_SCHEMA_VERSION,
|
|
420
428
|
"category": _serialize_category(form_definition.category),
|
|
@@ -452,7 +460,8 @@ def serialize_form(form_definition):
|
|
|
452
460
|
"payment_description_template": form_definition.payment_description_template,
|
|
453
461
|
},
|
|
454
462
|
"fields": [
|
|
455
|
-
_serialize_field(f
|
|
463
|
+
_serialize_field(f, wf_pk_to_index)
|
|
464
|
+
for f in form_definition.fields.all().order_by("order")
|
|
456
465
|
],
|
|
457
466
|
"workflow": _serialize_workflow(primary_workflow),
|
|
458
467
|
"post_actions": [
|
|
@@ -792,11 +801,13 @@ def _import_single_workflow(
|
|
|
792
801
|
if isinstance(entry, dict):
|
|
793
802
|
group = _get_or_create_group(entry["name"])
|
|
794
803
|
position = entry.get("position", pos)
|
|
804
|
+
role = entry.get("role", "approval")
|
|
795
805
|
else:
|
|
796
806
|
group = _get_or_create_group(entry)
|
|
797
807
|
position = pos
|
|
808
|
+
role = "approval"
|
|
798
809
|
StageApprovalGroup.objects.create(
|
|
799
|
-
stage=stage, group=group, position=position
|
|
810
|
+
stage=stage, group=group, position=position, role=role
|
|
800
811
|
)
|
|
801
812
|
|
|
802
813
|
stage.notification_rules.all().delete()
|
|
@@ -903,6 +914,8 @@ def import_form(form_data, conflict="update", category_cache=None):
|
|
|
903
914
|
|
|
904
915
|
# ── Workflows (created BEFORE fields so stage FKs can be resolved) ─────────
|
|
905
916
|
stage_order_map = {} # order → WorkflowStage, used when creating fields
|
|
917
|
+
# Per-workflow stage maps: wf_index → {order → WorkflowStage}
|
|
918
|
+
stage_order_maps_by_wf = {}
|
|
906
919
|
wf_data = form_data.get("workflow")
|
|
907
920
|
additional_wf_data = form_data.get("additional_workflows", [])
|
|
908
921
|
|
|
@@ -928,7 +941,9 @@ def import_form(form_data, conflict="update", category_cache=None):
|
|
|
928
941
|
imported_wf_ids,
|
|
929
942
|
)
|
|
930
943
|
imported_wf_ids.add(wf_obj.pk)
|
|
931
|
-
|
|
944
|
+
stage_order_maps_by_wf[wf_idx] = s_map
|
|
945
|
+
# Primary workflow's stage map is the default for backward compat
|
|
946
|
+
# (fields without workflow_index fall back to this).
|
|
932
947
|
if wf_idx == 0:
|
|
933
948
|
stage_order_map = s_map
|
|
934
949
|
|
|
@@ -994,9 +1009,18 @@ def import_form(form_data, conflict="update", category_cache=None):
|
|
|
994
1009
|
min_val = field_data.pop("min_value", None)
|
|
995
1010
|
max_val = field_data.pop("max_value", None)
|
|
996
1011
|
stage_order = field_data.pop("workflow_stage_order", None)
|
|
997
|
-
|
|
998
|
-
|
|
999
|
-
|
|
1012
|
+
wf_index = field_data.pop("workflow_index", None)
|
|
1013
|
+
if stage_order is not None:
|
|
1014
|
+
# Use the per-workflow stage map when workflow_index is present,
|
|
1015
|
+
# falling back to the primary workflow's map for backward compat.
|
|
1016
|
+
resolved_map = (
|
|
1017
|
+
stage_order_maps_by_wf.get(wf_index, stage_order_map)
|
|
1018
|
+
if wf_index is not None
|
|
1019
|
+
else stage_order_map
|
|
1020
|
+
)
|
|
1021
|
+
workflow_stage = resolved_map.get(stage_order)
|
|
1022
|
+
else:
|
|
1023
|
+
workflow_stage = None
|
|
1000
1024
|
# Resolve shared option list by slug (if present)
|
|
1001
1025
|
sol_slug = field_data.pop("shared_option_list_slug", None)
|
|
1002
1026
|
shared_option_list = None
|
{django_forms_workflows-0.64.2 → django_forms_workflows-0.65.1}/django_forms_workflows/views.py
RENAMED
|
@@ -1925,13 +1925,13 @@ def reassign_task(request, task_id):
|
|
|
1925
1925
|
messages.error(request, "Reassignment is not enabled for this approval step.")
|
|
1926
1926
|
return redirect("forms_workflows:approval_inbox")
|
|
1927
1927
|
|
|
1928
|
-
# Permission: current assignee, any member of the stage's
|
|
1929
|
-
# or superuser can reassign.
|
|
1930
|
-
|
|
1931
|
-
|
|
1928
|
+
# Permission: current assignee, any member of the stage's reassignment
|
|
1929
|
+
# groups (falls back to approval groups), or superuser can reassign.
|
|
1930
|
+
reassign_groups = list(stage.get_reassignment_groups())
|
|
1931
|
+
reassign_group_ids = {g.pk for g in reassign_groups}
|
|
1932
1932
|
can_reassign = (
|
|
1933
1933
|
task.assigned_to == request.user
|
|
1934
|
-
or request.user.groups.filter(pk__in=
|
|
1934
|
+
or request.user.groups.filter(pk__in=reassign_group_ids).exists()
|
|
1935
1935
|
or request.user.is_superuser
|
|
1936
1936
|
)
|
|
1937
1937
|
if not can_reassign:
|
|
@@ -1950,11 +1950,11 @@ def reassign_task(request, task_id):
|
|
|
1950
1950
|
messages.error(request, "Selected user not found.")
|
|
1951
1951
|
return redirect("forms_workflows:reassign_task", task_id=task_id)
|
|
1952
1952
|
|
|
1953
|
-
# Validate the new assignee is in one of the stage's
|
|
1954
|
-
if not new_assignee.groups.filter(pk__in=
|
|
1953
|
+
# Validate the new assignee is in one of the stage's reassignment groups
|
|
1954
|
+
if not new_assignee.groups.filter(pk__in=reassign_group_ids).exists():
|
|
1955
1955
|
messages.error(
|
|
1956
1956
|
request,
|
|
1957
|
-
"The selected user is not a member of any
|
|
1957
|
+
"The selected user is not a member of any reassignment group for this stage.",
|
|
1958
1958
|
)
|
|
1959
1959
|
return redirect("forms_workflows:reassign_task", task_id=task_id)
|
|
1960
1960
|
|
|
@@ -1988,7 +1988,7 @@ def reassign_task(request, task_id):
|
|
|
1988
1988
|
|
|
1989
1989
|
# GET — show reassignment form with eligible users
|
|
1990
1990
|
eligible_users = (
|
|
1991
|
-
user_model.objects.filter(groups__pk__in=
|
|
1991
|
+
user_model.objects.filter(groups__pk__in=reassign_group_ids, is_active=True)
|
|
1992
1992
|
.distinct()
|
|
1993
1993
|
.order_by("last_name", "first_name", "username")
|
|
1994
1994
|
)
|
|
@@ -129,9 +129,14 @@ def _normalize_trigger_conditions(raw_conditions):
|
|
|
129
129
|
|
|
130
130
|
def _serialize_stage_approval_groups(stage):
|
|
131
131
|
return [
|
|
132
|
-
{
|
|
132
|
+
{
|
|
133
|
+
"id": sag.group_id,
|
|
134
|
+
"name": sag.group.name,
|
|
135
|
+
"position": sag.position,
|
|
136
|
+
"role": sag.role,
|
|
137
|
+
}
|
|
133
138
|
for sag in stage.stageapprovalgroup_set.select_related("group").order_by(
|
|
134
|
-
"position", "group__name"
|
|
139
|
+
"role", "position", "group__name"
|
|
135
140
|
)
|
|
136
141
|
]
|
|
137
142
|
|
|
@@ -1245,6 +1250,7 @@ def convert_visual_to_workflow(workflow_data, form_definition, workflow=None):
|
|
|
1245
1250
|
stage=stage,
|
|
1246
1251
|
group_id=group_entry["id"],
|
|
1247
1252
|
position=group_entry.get("position", pos),
|
|
1253
|
+
role=group_entry.get("role", "approval"),
|
|
1248
1254
|
)
|
|
1249
1255
|
|
|
1250
1256
|
stage_node_map[snode.get("id")] = stage
|
|
@@ -586,12 +586,14 @@ def _create_stage_tasks(
|
|
|
586
586
|
# --- Dynamic assignment (form field → User lookup) ------------------------
|
|
587
587
|
dynamic_assignee = _resolve_dynamic_assignee(submission, stage)
|
|
588
588
|
if dynamic_assignee is not None:
|
|
589
|
-
# Optionally validate the resolved user belongs to
|
|
589
|
+
# Optionally validate the resolved user belongs to the stage's
|
|
590
|
+
# validation groups (falls back to approval groups when none defined).
|
|
590
591
|
if stage.validate_assignee_group and groups:
|
|
591
|
-
|
|
592
|
-
|
|
592
|
+
validation_groups = list(stage.get_validation_groups())
|
|
593
|
+
validation_group_ids = {g.pk for g in validation_groups}
|
|
594
|
+
if not dynamic_assignee.groups.filter(pk__in=validation_group_ids).exists():
|
|
593
595
|
logger.warning(
|
|
594
|
-
"Dynamic assignee '%s' is not a member of any
|
|
596
|
+
"Dynamic assignee '%s' is not a member of any validation group "
|
|
595
597
|
"for stage '%s' (submission %s); falling back to group assignment.",
|
|
596
598
|
dynamic_assignee.username,
|
|
597
599
|
stage.name,
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
{django_forms_workflows-0.64.2 → django_forms_workflows-0.65.1}/django_forms_workflows/__init__.py
RENAMED
|
File without changes
|
{django_forms_workflows-0.64.2 → django_forms_workflows-0.65.1}/django_forms_workflows/api_urls.py
RENAMED
|
File without changes
|
{django_forms_workflows-0.64.2 → django_forms_workflows-0.65.1}/django_forms_workflows/api_views.py
RENAMED
|
File without changes
|
{django_forms_workflows-0.64.2 → django_forms_workflows-0.65.1}/django_forms_workflows/apps.py
RENAMED
|
File without changes
|
|
File without changes
|
{django_forms_workflows-0.64.2 → django_forms_workflows-0.65.1}/django_forms_workflows/conditions.py
RENAMED
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
{django_forms_workflows-0.64.2 → django_forms_workflows-0.65.1}/django_forms_workflows/diff_views.py
RENAMED
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
{django_forms_workflows-0.64.2 → django_forms_workflows-0.65.1}/django_forms_workflows/forms.py
RENAMED
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
{django_forms_workflows-0.64.2 → django_forms_workflows-0.65.1}/django_forms_workflows/history.py
RENAMED
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|