curation_concerns 1.6.3 → 1.7.0.beta1
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/.rubocop.yml +4 -0
- data/.travis.yml +2 -8
- data/README.md +27 -1
- data/app/actors/curation_concerns/actors/base_actor.rb +2 -3
- data/app/actors/curation_concerns/actors/file_set_actor.rb +1 -1
- data/app/actors/curation_concerns/actors/grant_edit_to_depositor_actor.rb +19 -0
- data/app/actors/curation_concerns/actors/initialize_workflow_actor.rb +19 -0
- data/app/assets/javascripts/curation_concerns/charts.js +47 -0
- data/app/assets/javascripts/curation_concerns/curation_concerns.js +2 -0
- data/app/assets/javascripts/curation_concerns/workflow_actions_affix.js +11 -0
- data/app/assets/stylesheets/curation_concerns/_admin.scss +18 -0
- data/app/assets/stylesheets/curation_concerns/_curation_concerns.scss +1 -0
- data/app/assets/stylesheets/curation_concerns/_positioning.scss +11 -0
- data/app/controllers/concerns/curation_concerns/act_as_admin_controller.rb +25 -0
- data/app/controllers/concerns/curation_concerns/admin_controller_behavior.rb +38 -0
- data/app/controllers/concerns/curation_concerns/admin_page.rb +18 -0
- data/app/controllers/concerns/curation_concerns/collections_controller_behavior.rb +3 -2
- data/app/controllers/concerns/curation_concerns/curation_concern_controller.rb +158 -159
- data/app/controllers/concerns/curation_concerns/embargoes_controller_behavior.rb +4 -6
- data/app/controllers/concerns/curation_concerns/file_sets_controller_behavior.rb +2 -1
- data/app/controllers/concerns/curation_concerns/leases_controller_behavior.rb +4 -6
- data/app/controllers/concerns/curation_concerns/single_use_links_viewer_controller_behavior.rb +2 -1
- data/app/controllers/curation_concerns/admin/workflow_roles_controller.rb +36 -0
- data/app/controllers/curation_concerns/workflow_actions_controller.rb +25 -0
- data/app/conversions/power_converters/polymorphic_type.rb +7 -0
- data/app/conversions/power_converters/sipity_action.rb +9 -0
- data/app/conversions/power_converters/sipity_action_name.rb +8 -0
- data/app/conversions/power_converters/sipity_agent.rb +6 -0
- data/app/conversions/power_converters/sipity_entity.rb +12 -0
- data/app/conversions/power_converters/sipity_role.rb +8 -0
- data/app/conversions/power_converters/sipity_workflow_id.rb +16 -0
- data/app/conversions/power_converters/sipity_workflow_state.rb +10 -0
- data/app/conversions/power_converters.rb +6 -0
- data/app/forms/curation_concerns/forms/workflow_action_form.rb +62 -0
- data/app/forms/curation_concerns/forms/workflow_responsibility_form.rb +42 -0
- data/app/helpers/curation_concerns/charts_helper.rb +23 -0
- data/app/helpers/curation_concerns/main_app_helpers.rb +1 -0
- data/app/helpers/curation_concerns/url_helper.rb +2 -5
- data/app/indexers/curation_concerns/indexes_workflow.rb +44 -0
- data/app/indexers/curation_concerns/work_indexer.rb +1 -2
- data/app/jobs/import_export_job.rb +46 -0
- data/app/models/concerns/curation_concerns/ability.rb +2 -0
- data/app/models/concerns/curation_concerns/permissions/writable.rb +7 -8
- data/app/models/concerns/curation_concerns/publishable.rb +6 -0
- data/app/models/concerns/curation_concerns/solr_document_behavior.rb +8 -0
- data/app/models/concerns/curation_concerns/user.rb +5 -0
- data/app/models/curation_concerns/group.rb +23 -0
- data/app/models/curation_concerns/workflow_action_info.rb +13 -0
- data/app/models/sipity/agent.rb +21 -0
- data/app/models/sipity/comment.rb +13 -0
- data/app/models/sipity/entity.rb +32 -0
- data/app/models/sipity/entity_specific_responsibility.rb +21 -0
- data/app/models/sipity/method.rb +5 -0
- data/app/models/sipity/notifiable_context.rb +26 -0
- data/app/models/sipity/notification.rb +28 -0
- data/app/models/sipity/notification_recipient.rb +17 -0
- data/app/models/sipity/role.rb +43 -0
- data/app/models/sipity/workflow.rb +19 -0
- data/app/models/sipity/workflow_action.rb +25 -0
- data/app/models/sipity/workflow_responsibility.rb +23 -0
- data/app/models/sipity/workflow_role.rb +13 -0
- data/app/models/sipity/workflow_state.rb +26 -0
- data/app/models/sipity/workflow_state_action.rb +9 -0
- data/app/models/sipity/workflow_state_action_permission.rb +8 -0
- data/app/models/vocab/fedora_resource_status.rb +4 -1
- data/app/presenters/curation_concerns/admin/workflow_role_presenter.rb +40 -0
- data/app/presenters/curation_concerns/work_show_presenter.rb +4 -0
- data/app/presenters/curation_concerns/workflow_presenter.rb +43 -0
- data/app/renderers/curation_concerns/renderers/rights_attribute_renderer.rb +1 -1
- data/app/search_builders/curation_concerns/search_filters.rb +0 -1
- data/app/services/curation_concerns/actors/actor_factory.rb +3 -1
- data/app/services/curation_concerns/admin_set_service.rb +13 -4
- data/app/services/curation_concerns/work_form_service.rb +11 -0
- data/app/services/curation_concerns/workflow/action_taken_service.rb +57 -0
- data/app/services/curation_concerns/workflow/activate_object.rb +9 -0
- data/app/services/curation_concerns/workflow/deactivate_object.rb +11 -0
- data/app/services/curation_concerns/workflow/default_workflow_strategy.rb +13 -0
- data/app/services/curation_concerns/workflow/method_generator.rb +55 -0
- data/app/services/curation_concerns/workflow/notification_configuration_parameter.rb +42 -0
- data/app/services/curation_concerns/workflow/notification_generator.rb +64 -0
- data/app/services/curation_concerns/workflow/notification_service.rb +66 -0
- data/app/services/curation_concerns/workflow/permission_generator.rb +95 -0
- data/app/services/curation_concerns/workflow/permission_query.rb +432 -0
- data/app/services/curation_concerns/workflow/remove_depositor_permissions.rb +11 -0
- data/app/services/curation_concerns/workflow/sipity_actions_generator.rb +49 -0
- data/app/services/curation_concerns/workflow/state_machine_generator.rb +102 -0
- data/app/services/curation_concerns/workflow/status_list_service.rb +52 -0
- data/app/services/curation_concerns/workflow/workflow_action_service.rb +56 -0
- data/app/services/curation_concerns/workflow/workflow_by_model_name_strategy.rb +14 -0
- data/app/services/curation_concerns/workflow/workflow_factory.rb +64 -0
- data/app/services/curation_concerns/workflow/workflow_importer.rb +103 -0
- data/app/services/curation_concerns/workflow/workflow_permissions_generator.rb +49 -0
- data/app/services/curation_concerns/workflow/workflow_schema.rb +56 -0
- data/app/services/rights_service.rb +1 -1
- data/app/services/sipity.rb +2 -0
- data/app/sources/curation_concerns/resource_statistics_source.rb +101 -0
- data/app/values/curation_concerns/chart_data.rb +61 -0
- data/app/views/curation_concerns/admin/_admin_menu.html.erb +5 -0
- data/app/views/curation_concerns/admin/_resource_stats.html.erb +43 -0
- data/app/views/curation_concerns/admin/_sidebar.html.erb +3 -0
- data/app/views/curation_concerns/admin/_total_embargo_visibility.html.erb +21 -0
- data/app/views/curation_concerns/admin/_total_objects.html.erb +1 -0
- data/app/views/curation_concerns/admin/_total_objects_charts.html.erb +12 -0
- data/app/views/curation_concerns/admin/index.html.erb +11 -0
- data/app/views/curation_concerns/admin/widgets/_pie.html.erb +1 -0
- data/app/views/curation_concerns/admin/workflow.html.erb +31 -0
- data/app/views/curation_concerns/admin/workflow_roles/index.html.erb +45 -0
- data/app/views/curation_concerns/base/_form_rights.html.erb +1 -1
- data/app/views/curation_concerns/base/_workflow_actions.html.erb +39 -0
- data/app/views/curation_concerns/base/show.html.erb +2 -0
- data/app/views/curation_concerns/file_sets/media_display/_office_document.html.erb +0 -1
- data/app/views/layouts/_head_tag_content.html.erb +13 -0
- data/app/views/layouts/admin.html.erb +10 -0
- data/app/views/shared/_my_actions.html.erb +4 -1
- data/config/initializers/precompile_assets.rb +1 -0
- data/config/locales/curation_concerns.en.yml +97 -56
- data/config/routes.rb +7 -0
- data/curation_concerns.gemspec +9 -3
- data/db/migrate/20160919151348_create_sipity.rb +163 -0
- data/db/migrate/20161012182404_create_sipity_workflow_methods.rb +10 -0
- data/lib/curation_concerns/configuration.rb +68 -0
- data/lib/curation_concerns/engine.rb +9 -1
- data/lib/curation_concerns/rails/routes.rb +1 -0
- data/lib/curation_concerns/version.rb +1 -1
- data/lib/curation_concerns.rb +1 -1
- data/lib/generators/curation_concerns/admin_dashboard_generator.rb +15 -0
- data/lib/generators/curation_concerns/install_generator.rb +7 -0
- data/lib/generators/curation_concerns/sample_data_generator.rb +12 -0
- data/lib/generators/curation_concerns/templates/app/controllers/curation_concerns/admin_controller.rb +61 -0
- data/lib/generators/curation_concerns/templates/catalog_controller.rb +1 -3
- data/lib/generators/curation_concerns/templates/config/curation_concerns.rb +39 -0
- data/lib/generators/curation_concerns/templates/db/seeds.rb +94 -0
- data/lib/generators/curation_concerns/templates/spec/models/collection_spec.rb +1 -1
- data/lib/generators/curation_concerns/templates/spec/models/file_set_spec.rb +1 -1
- data/lib/generators/curation_concerns/templates/workflow.json.erb +19 -0
- data/lib/generators/curation_concerns/work/USAGE +1 -0
- data/lib/generators/curation_concerns/work/templates/actor_spec.rb.erb +1 -1
- data/lib/generators/curation_concerns/work/templates/controller_spec.rb.erb +1 -1
- data/lib/generators/curation_concerns/work/templates/feature_spec.rb.erb +1 -1
- data/lib/generators/curation_concerns/work/templates/form_spec.rb.erb +1 -1
- data/lib/generators/curation_concerns/work/templates/model_spec.rb.erb +1 -1
- data/spec/abilities/admin_ability_spec.rb +15 -0
- data/spec/actors/curation_concerns/file_set_actor_spec.rb +24 -0
- data/spec/actors/curation_concerns/grant_edit_to_depositor_actor_spec.rb +32 -0
- data/spec/actors/curation_concerns/initialize_workflow_actor_spec.rb +33 -0
- data/spec/actors/curation_concerns/interpret_visibility_actor_spec.rb +1 -0
- data/spec/actors/curation_concerns/work_actor_spec.rb +10 -5
- data/spec/controllers/curation_concerns/acts_as_admin_controller_spec.rb +22 -0
- data/spec/controllers/curation_concerns/admin/workflow_roles_controller_spec.rb +26 -0
- data/spec/controllers/curation_concerns/admin_controller_spec.rb +64 -0
- data/spec/controllers/curation_concerns/generic_works_controller_json_spec.rb +11 -3
- data/spec/controllers/curation_concerns/generic_works_controller_spec.rb +4 -4
- data/spec/controllers/curation_concerns/workflow_actions_controller_spec.rb +36 -0
- data/spec/conversions/power_converters/polymorphic_type_spec.rb +22 -0
- data/spec/conversions/power_converters/sipity_action_name_spec.rb +32 -0
- data/spec/conversions/power_converters/sipity_action_spec.rb +43 -0
- data/spec/conversions/power_converters/sipity_agent_spec.rb +20 -0
- data/spec/conversions/power_converters/sipity_entity_spec.rb +46 -0
- data/spec/conversions/power_converters/sipity_role_spec.rb +33 -0
- data/spec/conversions/power_converters/sipity_workflow_id_spec.rb +28 -0
- data/spec/conversions/power_converters/sipity_workflow_state_spec.rb +22 -0
- data/spec/factories/generic_works.rb +19 -6
- data/spec/factories/sipity_entities.rb +7 -0
- data/spec/factories/workflow_actions.rb +6 -0
- data/spec/factories/workflow_states.rb +6 -0
- data/spec/factories/workflows.rb +5 -0
- data/spec/features/admin_spec.rb +14 -0
- data/spec/features/create_child_work_spec.rb +1 -1
- data/spec/features/create_work_spec.rb +1 -1
- data/spec/features/embargo_spec.rb +1 -1
- data/spec/features/lease_spec.rb +1 -1
- data/spec/features/work_generator_spec.rb +2 -2
- data/spec/features/workflow_roles_spec.rb +48 -0
- data/spec/forms/curation_concerns/forms/workflow_action_form_spec.rb +111 -0
- data/spec/forms/curation_concerns/forms/workflow_responsibility_form_spec.rb +33 -0
- data/spec/helpers/curation_concerns/charts_helper_spec.rb +62 -0
- data/spec/helpers/url_helper_spec.rb +11 -11
- data/spec/indexers/work_indexer_spec.rb +13 -1
- data/spec/javascripts/charts_spec.coffee +10 -0
- data/spec/javascripts/fixtures/chart_example.html +1 -0
- data/spec/jobs/import_export_job_spec.rb +28 -0
- data/spec/models/curation_concerns/group_spec.rb +15 -0
- data/spec/models/file_set_spec.rb +6 -2
- data/spec/models/generic_work_spec.rb +12 -0
- data/spec/models/sipity/agent_spec.rb +9 -0
- data/spec/models/sipity/comment_spec.rb +16 -0
- data/spec/models/sipity/entity_spec.rb +27 -0
- data/spec/models/sipity/entity_specific_responsibility_spec.rb +8 -0
- data/spec/models/sipity/notifiable_context_spec.rb +8 -0
- data/spec/models/sipity/notification_recipient_spec.rb +10 -0
- data/spec/models/sipity/notification_spec.rb +15 -0
- data/spec/models/sipity/role_spec.rb +30 -0
- data/spec/models/sipity/workflow_action_spec.rb +10 -0
- data/spec/models/sipity/workflow_responsibility_spec.rb +7 -0
- data/spec/models/sipity/workflow_role_spec.rb +7 -0
- data/spec/models/sipity/workflow_spec.rb +15 -0
- data/spec/models/sipity/workflow_state_action_permission_spec.rb +7 -0
- data/spec/models/sipity/workflow_state_action_spec.rb +7 -0
- data/spec/models/sipity/workflow_state_spec.rb +7 -0
- data/spec/models/user_spec.rb +12 -1
- data/spec/presenters/curation_concerns/work_show_presenter_spec.rb +12 -1
- data/spec/presenters/curation_concerns/workflow_presenter_spec.rb +39 -0
- data/spec/routing/route_spec.rb +13 -0
- data/spec/services/curation_concerns/admin_set_service_spec.rb +13 -0
- data/spec/services/curation_concerns/qa_select_service_spec.rb +75 -0
- data/spec/services/curation_concerns/workflow/action_taken_service_spec.rb +76 -0
- data/spec/services/curation_concerns/workflow/activate_object_spec.rb +20 -0
- data/spec/services/curation_concerns/workflow/deactivate_object_spec.rb +20 -0
- data/spec/services/curation_concerns/workflow/method_generator_spec.rb +43 -0
- data/spec/services/curation_concerns/workflow/notification_configuration_parameter_spec.rb +25 -0
- data/spec/services/curation_concerns/workflow/notification_generator_spec.rb +27 -0
- data/spec/services/curation_concerns/workflow/notification_service_spec.rb +81 -0
- data/spec/services/curation_concerns/workflow/permission_generator_spec.rb +52 -0
- data/spec/services/curation_concerns/workflow/permission_query_spec.rb +179 -0
- data/spec/services/curation_concerns/workflow/remove_depositor_permissions_spec.rb +21 -0
- data/spec/services/curation_concerns/workflow/sipity_actions_generator_spec.rb +30 -0
- data/spec/services/curation_concerns/workflow/state_machine_generator_spec.rb +46 -0
- data/spec/services/curation_concerns/workflow/status_list_service_spec.rb +46 -0
- data/spec/services/curation_concerns/workflow/workflow_importer_spec.rb +50 -0
- data/spec/services/curation_concerns/workflow/workflow_permissions_generator_spec.rb +37 -0
- data/spec/services/curation_concerns/workflow/workflow_schema_spec.rb +85 -0
- data/spec/sources/curation_concerns/resource_statistics_source_spec.rb +137 -0
- data/spec/spec_helper.rb +8 -1
- data/spec/test_app_templates/lib/generators/test_app_generator.rb +11 -0
- data/spec/views/curation_concerns/admin/_admin_menu.html.erb_spec.rb +23 -0
- data/spec/views/curation_concerns/admin/_resource_stats.html.erb_spec.rb +33 -0
- data/spec/views/curation_concerns/admin/_total_objects_charts.html.erb_spec.rb +28 -0
- data/spec/views/curation_concerns/admin/index.html.erb_spec.rb +26 -0
- data/spec/views/curation_concerns/admin/widgets/_pie.html.erb_spec.rb +17 -0
- data/spec/views/curation_concerns/base/file_manager.html.erb_spec.rb +1 -1
- data/spec/views/curation_concerns/base/show.html.erb_spec.rb +33 -0
- data/spec/views/curation_concerns/permissions/confirm.html.erb_spec.rb +1 -1
- data/spec/views/shared/_my_actions.html.erb_spec.rb +1 -0
- data/tasks/workflow.rake +8 -0
- metadata +335 -21
@@ -0,0 +1,432 @@
|
|
1
|
+
module CurationConcerns
|
2
|
+
module Workflow
|
3
|
+
# Welcome intrepid developer. You have stumbled into some complex data
|
4
|
+
# interactions. There are a lot of data collaborators regarding these tests.
|
5
|
+
# I would love this to be more in isolation, but that is not in the cards as
|
6
|
+
# there are at least 16 database tables interacting to ultimately answer the
|
7
|
+
# following question:
|
8
|
+
#
|
9
|
+
# * What actions can a given user take on an entity?
|
10
|
+
#
|
11
|
+
# Could there be more efficient queries? Yes. However, the composition of
|
12
|
+
# queries has proven to be a very powerful means of understanding and
|
13
|
+
# exploring the problem.
|
14
|
+
#
|
15
|
+
# @note There is an indication of public or private api. The intent of this
|
16
|
+
# is to differentiate what are methods that are the primary entry points
|
17
|
+
# as understood as of the commit that has the @api tag. However, these are
|
18
|
+
# public methods because they have been tested in isolation and are used
|
19
|
+
# to help compose the `@api public` methods.
|
20
|
+
module PermissionQuery
|
21
|
+
module_function
|
22
|
+
|
23
|
+
# @api public
|
24
|
+
#
|
25
|
+
# For the given :user and :entity return only workflow actions that meet all of the following:
|
26
|
+
#
|
27
|
+
# * available for the :entity's workflow state
|
28
|
+
# * permitted to be taken by one or more roles in which the user is assigned
|
29
|
+
# either at the workflow level or the entity level.
|
30
|
+
#
|
31
|
+
# * Actions to which the user Only actions permitted to the user
|
32
|
+
#
|
33
|
+
# @param user [User]
|
34
|
+
# @param entity [#to_sipity_entity] an object that can be converted into a Sipity::Entity
|
35
|
+
# @return [ActiveRecord::Relation<Sipity::WorkflowAction>]
|
36
|
+
def scope_permitted_workflow_actions_available_for_current_state(user:, entity:)
|
37
|
+
workflow_actions_scope = scope_workflow_actions_available_for_current_state(entity: entity)
|
38
|
+
workflow_state_actions_scope = scope_permitted_entity_workflow_state_actions(user: user, entity: entity)
|
39
|
+
workflow_actions_scope.where(
|
40
|
+
workflow_actions_scope.arel_table[:id].in(
|
41
|
+
workflow_state_actions_scope.arel_table.project(
|
42
|
+
workflow_state_actions_scope.arel_table[:workflow_action_id]
|
43
|
+
).where(workflow_state_actions_scope.constraints.reduce)
|
44
|
+
)
|
45
|
+
)
|
46
|
+
end
|
47
|
+
|
48
|
+
# @api public
|
49
|
+
#
|
50
|
+
# Agents associated with the given :entity and how they are associated
|
51
|
+
# with the given.
|
52
|
+
#
|
53
|
+
# @param entity [Object] that can be converted into a Sipity::Entity
|
54
|
+
# @param role [Object] that can be converted into a Sipity::Role
|
55
|
+
# @return [ActiveRecord::Relation<Sipity::Agent>] augmented with
|
56
|
+
def scope_agents_associated_with_entity_and_role(entity:, role:)
|
57
|
+
entity = PowerConverter.convert_to_sipity_entity(entity)
|
58
|
+
role = PowerConverter.convert_to_sipity_role(role)
|
59
|
+
workflow_roles = Sipity::WorkflowRole.arel_table
|
60
|
+
workflow_responsibilities = Sipity::WorkflowResponsibility.arel_table
|
61
|
+
entity_responsibilities = Sipity::EntitySpecificResponsibility.arel_table
|
62
|
+
|
63
|
+
agents = Sipity::Agent.arel_table
|
64
|
+
|
65
|
+
agents_select_manager = agents.project(
|
66
|
+
:*,
|
67
|
+
Arel.sql("'#{Sipity::Agent::ENTITY_LEVEL_AGENT_RELATIONSHIP}'").as('agent_processing_relationship')
|
68
|
+
).where(
|
69
|
+
agents[:id].in(
|
70
|
+
entity_responsibilities.project(entity_responsibilities[:agent_id]).join(workflow_roles).on(
|
71
|
+
workflow_roles[:id].eq(entity_responsibilities[:workflow_role_id])
|
72
|
+
).where(
|
73
|
+
entity_responsibilities[:entity_id].eq(entity.id).and(
|
74
|
+
workflow_roles[:role_id].eq(role.id)
|
75
|
+
)
|
76
|
+
)
|
77
|
+
)
|
78
|
+
).union(
|
79
|
+
agents.project(
|
80
|
+
:*,
|
81
|
+
Arel.sql("'#{Sipity::Agent::WORKFLOW_LEVEL_AGENT_RELATIONSHIP}'").as('agent_processing_relationship')
|
82
|
+
).where(
|
83
|
+
agents[:id].in(
|
84
|
+
workflow_responsibilities.project(workflow_responsibilities[:agent_id]).join(workflow_roles).on(
|
85
|
+
workflow_roles[:id].eq(workflow_responsibilities[:workflow_role_id])
|
86
|
+
).where(
|
87
|
+
workflow_roles[:workflow_id].eq(entity.workflow_id).and(
|
88
|
+
workflow_roles[:role_id].eq(role.id)
|
89
|
+
)
|
90
|
+
)
|
91
|
+
)
|
92
|
+
)
|
93
|
+
)
|
94
|
+
# I would love to use the following:
|
95
|
+
# `Agent.find_by_sql(agents_select_manager.to_sql)`
|
96
|
+
#
|
97
|
+
# However AREL is adding an opening and closing parenthesis to the query
|
98
|
+
# statement. So I needed to massage that output, as follows:
|
99
|
+
#
|
100
|
+
# ```ruby
|
101
|
+
# Agent.find_by_sql(
|
102
|
+
# agents_select_manager.to_sql.sub(/\A\s*\(\s*(.*)\s*\)\s*\Z/,'\1')
|
103
|
+
# )
|
104
|
+
# ```
|
105
|
+
#
|
106
|
+
# Instead I'm taking an example from:
|
107
|
+
# https://github.com/danshultz/mastering_active_record_sample_code/blob/a656c60ca7a2e27b5cd1aadbdf3bdc1814c37000/app/models/beer.rb#L77-L81
|
108
|
+
#
|
109
|
+
# Note, I'm making a dynamic query with a result the same as the table
|
110
|
+
# name of the model that I'm using.
|
111
|
+
Sipity::Agent.from(agents.create_table_alias(agents_select_manager, agents.table_name)).all
|
112
|
+
end
|
113
|
+
|
114
|
+
# @api public
|
115
|
+
#
|
116
|
+
# Roles associated with the given :entity
|
117
|
+
# @param entity [Object] that can be converted into a Sipity::Entity
|
118
|
+
# @return [ActiveRecord::Relation<Sipity::Role>]
|
119
|
+
def scope_roles_associated_with_the_given_entity(entity:)
|
120
|
+
entity = PowerConverter.convert_to_sipity_entity(entity)
|
121
|
+
return Sipity::Role.none unless entity
|
122
|
+
workflow_roles = Sipity::WorkflowRole.arel_table
|
123
|
+
Sipity::Role.where(
|
124
|
+
Sipity::Role.arel_table[:id].in(
|
125
|
+
workflow_roles.project(workflow_roles[:role_id]).where(
|
126
|
+
workflow_roles[:workflow_id].eq(entity.workflow_id)
|
127
|
+
)
|
128
|
+
)
|
129
|
+
)
|
130
|
+
end
|
131
|
+
|
132
|
+
# @api public
|
133
|
+
#
|
134
|
+
# Is the user authorized to take the processing action on the given
|
135
|
+
# entity?
|
136
|
+
#
|
137
|
+
# @param user [User]
|
138
|
+
# @param entity an object that can be converted into a Sipity::Entity
|
139
|
+
# @param action an object that can be converted into a Sipity::WorkflowAction#name
|
140
|
+
# @return [Boolean]
|
141
|
+
def authorized_for_processing?(user:, entity:, action:)
|
142
|
+
action_name = PowerConverter.convert_to_sipity_action_name(action)
|
143
|
+
scope_permitted_workflow_actions_available_for_current_state(user: user, entity: entity)
|
144
|
+
.where(Sipity::WorkflowAction.arel_table[:name].eq(action_name)).count > 0
|
145
|
+
end
|
146
|
+
|
147
|
+
# @api public
|
148
|
+
#
|
149
|
+
# An ActiveRecord::Relation scope that meets the following criteria:
|
150
|
+
#
|
151
|
+
# * All of the Processing Agents directly associated with the given :user
|
152
|
+
#
|
153
|
+
# @param user [User]
|
154
|
+
# @return [ActiveRecord::Relation<Sipity::Agent>]
|
155
|
+
def scope_processing_agents_for(user:)
|
156
|
+
return Sipity::Agent.none unless user.present?
|
157
|
+
return Sipity::Agent.none unless user.persisted?
|
158
|
+
user_agent = PowerConverter.convert_to_sipity_agent(user)
|
159
|
+
group_agents = user.groups.map do |g|
|
160
|
+
PowerConverter.convert_to_sipity_agent(CurationConcerns::Group.new(g))
|
161
|
+
end
|
162
|
+
Sipity::Agent.where(id: group_agents + [user_agent])
|
163
|
+
end
|
164
|
+
|
165
|
+
PermissionScope = Struct.new(:entity, :workflow)
|
166
|
+
private_constant :PermissionScope
|
167
|
+
|
168
|
+
# @api public
|
169
|
+
#
|
170
|
+
# An ActiveRecord::Relation scope that meets the following criteria:
|
171
|
+
#
|
172
|
+
# * Sipity::Entity in a state in which I have access to based on:
|
173
|
+
# - The entity specific responsibility
|
174
|
+
# - For which I've been assigned a role
|
175
|
+
# - The workflow specific responsibility
|
176
|
+
# - For which I've been assigned a role
|
177
|
+
#
|
178
|
+
# @param [User] user
|
179
|
+
#
|
180
|
+
# @return [ActiveRecord::Relation<Sipity::Entity>]
|
181
|
+
def scope_entities_for_the_user(user:)
|
182
|
+
entities = Sipity::Entity.arel_table
|
183
|
+
workflow_state_actions = Sipity::WorkflowStateAction.arel_table
|
184
|
+
workflow_states = Sipity::WorkflowState.arel_table
|
185
|
+
workflow_state_action_permissions = Sipity::WorkflowStateActionPermission.arel_table
|
186
|
+
workflow_responsibilities = Sipity::WorkflowResponsibility.arel_table
|
187
|
+
entity_responsibilities = Sipity::EntitySpecificResponsibility.arel_table
|
188
|
+
|
189
|
+
user_agent_scope = scope_processing_agents_for(user: user)
|
190
|
+
user_agent_contraints = user_agent_scope.arel_table.project(
|
191
|
+
user_agent_scope.arel_table[:id]
|
192
|
+
).where(user_agent_scope.arel.constraints)
|
193
|
+
|
194
|
+
join_builder = lambda do |responsibility|
|
195
|
+
entities.project(
|
196
|
+
entities[:id]
|
197
|
+
).join(workflow_state_actions).on(
|
198
|
+
workflow_state_actions[:originating_workflow_state_id].eq(entities[:workflow_state_id])
|
199
|
+
).join(workflow_state_action_permissions).on(
|
200
|
+
workflow_state_action_permissions[:workflow_state_action_id].eq(workflow_state_actions[:id])
|
201
|
+
).join(workflow_states).on(
|
202
|
+
workflow_states[:id].eq(workflow_state_actions[:originating_workflow_state_id])
|
203
|
+
).join(responsibility).on(
|
204
|
+
responsibility[:workflow_role_id].eq(workflow_state_action_permissions[:workflow_role_id])
|
205
|
+
)
|
206
|
+
end
|
207
|
+
|
208
|
+
where_builder = -> (responsibility) { responsibility[:agent_id].in(user_agent_contraints) }
|
209
|
+
|
210
|
+
entity_specific_joins = join_builder.call(entity_responsibilities)
|
211
|
+
workflow_specific_joins = join_builder.call(workflow_responsibilities)
|
212
|
+
|
213
|
+
entity_specific_where = where_builder.call(entity_responsibilities).and(
|
214
|
+
entities[:id].eq(entity_responsibilities[:entity_id])
|
215
|
+
)
|
216
|
+
workflow_specific_where = where_builder.call(workflow_responsibilities)
|
217
|
+
|
218
|
+
Sipity::Entity.where(
|
219
|
+
entities[:id].in(entity_specific_joins.where(entity_specific_where))
|
220
|
+
.or(entities[:id].in(workflow_specific_joins.where(workflow_specific_where)))
|
221
|
+
)
|
222
|
+
end
|
223
|
+
|
224
|
+
# @api public
|
225
|
+
#
|
226
|
+
# An ActiveRecord::Relation scope that meets the following criteria:
|
227
|
+
#
|
228
|
+
# * Users that are directly associated with the given entity through on or
|
229
|
+
# more of the given roles
|
230
|
+
# * Users that are indirectly associated with the given entity by group
|
231
|
+
# and role.
|
232
|
+
#
|
233
|
+
# @param roles [Sipity::Role]
|
234
|
+
# @param entity an object that can be converted into a Sipity::Entity
|
235
|
+
# @return [ActiveRecord::Relation<User>]
|
236
|
+
def scope_users_for_entity_and_roles(entity:, roles:)
|
237
|
+
entity = PowerConverter.convert_to_sipity_entity(entity)
|
238
|
+
role_ids = Array.wrap(roles).map { |role| PowerConverter.convert_to_sipity_role(role).id }
|
239
|
+
user_polymorphic_type = PowerConverter.convert_to_polymorphic_type(::User)
|
240
|
+
|
241
|
+
workflow_roles = Sipity::WorkflowRole.arel_table
|
242
|
+
workflow_responsibilities = Sipity::WorkflowResponsibility.arel_table
|
243
|
+
entity_responsibilities = Sipity::EntitySpecificResponsibility.arel_table
|
244
|
+
user_table = ::User.arel_table
|
245
|
+
agent_table = Sipity::Agent.arel_table
|
246
|
+
|
247
|
+
workflow_role_id_subquery = workflow_roles.project(workflow_roles[:id]).where(
|
248
|
+
workflow_roles[:role_id].in(role_ids)
|
249
|
+
)
|
250
|
+
|
251
|
+
workflow_agent_id_subquery = workflow_responsibilities.project(workflow_responsibilities[:agent_id]).where(
|
252
|
+
workflow_responsibilities[:workflow_role_id].in(workflow_role_id_subquery)
|
253
|
+
)
|
254
|
+
|
255
|
+
entity_agent_id_subquery = entity_responsibilities.project(entity_responsibilities[:agent_id]).where(
|
256
|
+
entity_responsibilities[:workflow_role_id].in(workflow_role_id_subquery)
|
257
|
+
.and(entity_responsibilities[:entity_id].eq(entity.id))
|
258
|
+
)
|
259
|
+
|
260
|
+
sub_query_for_user = agent_table.project(agent_table[:proxy_for_id]).where(
|
261
|
+
agent_table[:id].in(workflow_agent_id_subquery)
|
262
|
+
.or(agent_table[:id].in(entity_agent_id_subquery))
|
263
|
+
).where(
|
264
|
+
agent_table[:proxy_for_type].eq(user_polymorphic_type)
|
265
|
+
)
|
266
|
+
|
267
|
+
::User.where(user_table[:id].in(sub_query_for_user))
|
268
|
+
end
|
269
|
+
|
270
|
+
def user_emails_for_entity_and_roles(entity:, roles:)
|
271
|
+
scope_users_for_entity_and_roles(entity: entity, roles: roles).pluck(:email)
|
272
|
+
end
|
273
|
+
|
274
|
+
# @api public
|
275
|
+
#
|
276
|
+
# For the given :user and :entity, return an ActiveRecord::Relation that,
|
277
|
+
# if resolved, will be all of the assocated workflow roles for both the
|
278
|
+
# workflow responsibilities and the entity specific responsibilities.
|
279
|
+
#
|
280
|
+
# @param user [User]
|
281
|
+
# @param entity an object that can be converted into a Sipity::Entity
|
282
|
+
# @return [ActiveRecord::Relation<Sipity::WorkflowRole>]
|
283
|
+
def scope_processing_workflow_roles_for_user_and_entity(user:, entity:)
|
284
|
+
entity = PowerConverter.convert_to_sipity_entity(entity)
|
285
|
+
workflow_scope = scope_processing_workflow_roles_for_user_and_workflow(user: user, workflow: entity.workflow)
|
286
|
+
|
287
|
+
entity_specific_scope = scope_processing_workflow_roles_for_user_and_entity_specific(user: user, entity: entity)
|
288
|
+
Sipity::WorkflowRole.where(
|
289
|
+
workflow_scope.arel.constraints.reduce.or(entity_specific_scope.arel.constraints.reduce)
|
290
|
+
)
|
291
|
+
end
|
292
|
+
|
293
|
+
# @api private
|
294
|
+
#
|
295
|
+
# For the given :user and :workflow, return an ActiveRecord::Relation that,
|
296
|
+
# if resolved, will be all of the assocated workflow roles that are
|
297
|
+
# assigned to directly to the workflow.
|
298
|
+
#
|
299
|
+
# @param user [User]
|
300
|
+
# @param workflow [Sipity::Workflow]
|
301
|
+
# @return [ActiveRecord::Relation<Sipity::WorkflowRole>]
|
302
|
+
def scope_processing_workflow_roles_for_user_and_workflow(user:, workflow:)
|
303
|
+
responsibility_table = Sipity::WorkflowResponsibility.arel_table
|
304
|
+
workflow_role_table = Sipity::WorkflowRole.arel_table
|
305
|
+
|
306
|
+
agent_constraints = scope_processing_agents_for(user: user)
|
307
|
+
workflow_role_subquery = workflow_role_table[:id].in(
|
308
|
+
responsibility_table.project(responsibility_table[:workflow_role_id])
|
309
|
+
.where(
|
310
|
+
responsibility_table[:agent_id].in(
|
311
|
+
agent_constraints.arel_table.project(
|
312
|
+
agent_constraints.arel_table[:id]
|
313
|
+
).where(agent_constraints.arel.constraints)
|
314
|
+
)
|
315
|
+
)
|
316
|
+
)
|
317
|
+
|
318
|
+
Sipity::WorkflowRole.where(
|
319
|
+
workflow_role_table[:workflow_id].eq(workflow.id).and(workflow_role_subquery)
|
320
|
+
)
|
321
|
+
end
|
322
|
+
|
323
|
+
# @api private
|
324
|
+
#
|
325
|
+
# For the given :user and :entity, return an ActiveRecord::Relation that,
|
326
|
+
# if resolved, will be all of the assocated workflow roles that are
|
327
|
+
# assigned to specifically to the entity (and not the parent workflow).
|
328
|
+
#
|
329
|
+
# @param user [User]
|
330
|
+
# @param entity an object that can be converted into a Sipity::Entity
|
331
|
+
# @return [ActiveRecord::Relation<Sipity::WorkflowRole>]
|
332
|
+
def scope_processing_workflow_roles_for_user_and_entity_specific(user:, entity:)
|
333
|
+
entity = PowerConverter.convert_to_sipity_entity(entity)
|
334
|
+
agent_scope = scope_processing_agents_for(user: user)
|
335
|
+
specific_resp_table = Sipity::EntitySpecificResponsibility.arel_table
|
336
|
+
workflow_role_table = Sipity::WorkflowRole.arel_table
|
337
|
+
|
338
|
+
Sipity::WorkflowRole.where(
|
339
|
+
workflow_role_table[:id].in(
|
340
|
+
specific_resp_table.project(specific_resp_table[:workflow_role_id])
|
341
|
+
.where(
|
342
|
+
specific_resp_table[:agent_id].in(
|
343
|
+
agent_scope.arel_table.project(
|
344
|
+
agent_scope.arel_table[:id]
|
345
|
+
).where(
|
346
|
+
agent_scope.arel.constraints.reduce.and(specific_resp_table[:entity_id].eq(entity.id))
|
347
|
+
)
|
348
|
+
)
|
349
|
+
)
|
350
|
+
)
|
351
|
+
)
|
352
|
+
end
|
353
|
+
|
354
|
+
# @api private
|
355
|
+
#
|
356
|
+
# For the given :user and :entity, return an ActiveRecord::Relation,
|
357
|
+
# that if resolved, will be collection of
|
358
|
+
# Sipity::WorkflowStateAction object to which the user has
|
359
|
+
# permission to do something.
|
360
|
+
#
|
361
|
+
# An ActiveRecord::Relation scope that meets the following criteria:
|
362
|
+
#
|
363
|
+
# * The actions are available for the given entity's current state
|
364
|
+
# * The actions are available for the given user based on their role.
|
365
|
+
# Either:
|
366
|
+
# - Directly via an agent associated with a user
|
367
|
+
# - Indirectly via an agent associated with a group
|
368
|
+
#
|
369
|
+
# @param user [User]
|
370
|
+
# @param entity an object that can be converted into a Sipity::Entity
|
371
|
+
# @return [ActiveRecord::Relation<Sipity::WorkflowStateAction>]
|
372
|
+
def scope_permitted_entity_workflow_state_actions(user:, entity:)
|
373
|
+
entity = PowerConverter.convert_to_sipity_entity(entity)
|
374
|
+
workflow_state_actions = Sipity::WorkflowStateAction
|
375
|
+
permissions = Sipity::WorkflowStateActionPermission
|
376
|
+
role_scope = scope_processing_workflow_roles_for_user_and_entity(user: user, entity: entity)
|
377
|
+
|
378
|
+
workflow_state_actions.where(
|
379
|
+
workflow_state_actions.arel_table[:originating_workflow_state_id].eq(entity.workflow_state_id).and(
|
380
|
+
workflow_state_actions.arel_table[:id].in(
|
381
|
+
permissions.arel_table.project(
|
382
|
+
permissions.arel_table[:workflow_state_action_id]
|
383
|
+
).where(
|
384
|
+
permissions.arel_table[:workflow_role_id].in(
|
385
|
+
role_scope.arel_table.project(role_scope.arel_table[:id]).where(
|
386
|
+
role_scope.arel.constraints.reduce
|
387
|
+
)
|
388
|
+
)
|
389
|
+
)
|
390
|
+
)
|
391
|
+
)
|
392
|
+
)
|
393
|
+
end
|
394
|
+
|
395
|
+
# @api public
|
396
|
+
#
|
397
|
+
# For the given :entity return an ActiveRecord::Relation that when
|
398
|
+
# resolved will be only the workflow actions that:
|
399
|
+
#
|
400
|
+
# * Are available for the entity's workflow_state
|
401
|
+
#
|
402
|
+
# @param entity an object that can be converted into a Sipity::Entity
|
403
|
+
# @return [ActiveRecord::Relation<Sipity::WorkflowAction>]
|
404
|
+
def scope_workflow_actions_for_current_state(entity:)
|
405
|
+
entity = PowerConverter.convert_to_sipity_entity(entity)
|
406
|
+
state_actions_table = Sipity::WorkflowStateAction.arel_table
|
407
|
+
Sipity::WorkflowAction.where(
|
408
|
+
Sipity::WorkflowAction.arel_table[:id].in(
|
409
|
+
state_actions_table.project(state_actions_table[:workflow_action_id])
|
410
|
+
.where(state_actions_table[:originating_workflow_state_id].eq(entity.workflow_state_id))
|
411
|
+
)
|
412
|
+
)
|
413
|
+
end
|
414
|
+
|
415
|
+
# @api private
|
416
|
+
#
|
417
|
+
# For the given :entity, return an ActiveRecord::Relation, that
|
418
|
+
# if resolved, that lists all of the actions available for the entity and
|
419
|
+
# its current state.
|
420
|
+
#
|
421
|
+
# * All actions that are associated with actions that do not have prerequsites
|
422
|
+
# * All actions that have prerequisites and all of those prerequisites are complete
|
423
|
+
#
|
424
|
+
# @param entity an object that can be converted into a Sipity::Entity
|
425
|
+
# @return [ActiveRecord::Relation<Sipity::WorkflowAction>]
|
426
|
+
def scope_workflow_actions_available_for_current_state(entity:)
|
427
|
+
workflow_actions_for_current_state = scope_workflow_actions_for_current_state(entity: entity)
|
428
|
+
Sipity::WorkflowAction.where(workflow_actions_for_current_state.constraints.reduce)
|
429
|
+
end
|
430
|
+
end
|
431
|
+
end
|
432
|
+
end
|
@@ -0,0 +1,11 @@
|
|
1
|
+
module CurationConcerns
|
2
|
+
module Workflow
|
3
|
+
# This is a built in function for workflow, so that a workflow action can be created that
|
4
|
+
# removes the creators ability to alter it.
|
5
|
+
class RemoveDepositorPermissions
|
6
|
+
def self.call(entity:, **)
|
7
|
+
entity.proxy_for.edit_users = []
|
8
|
+
end
|
9
|
+
end
|
10
|
+
end
|
11
|
+
end
|
@@ -0,0 +1,49 @@
|
|
1
|
+
module CurationConcerns
|
2
|
+
module Workflow
|
3
|
+
# Responsible for creating database entries for the given workflow's actions
|
4
|
+
class SipityActionsGenerator
|
5
|
+
# @api public
|
6
|
+
#
|
7
|
+
# Responsible for creating database entries for the given workflow's actions
|
8
|
+
#
|
9
|
+
# @param workflow [Sipity::Workflow]
|
10
|
+
# @param actions_configuration [Hash] as defined in CurationConcerns::Workflow::WorkflowSchema
|
11
|
+
# @return [Sipity::Workflow]
|
12
|
+
def self.call(**keywords, &block)
|
13
|
+
new(**keywords, &block).call
|
14
|
+
end
|
15
|
+
|
16
|
+
def initialize(workflow:, actions_configuration:)
|
17
|
+
self.workflow = workflow
|
18
|
+
self.actions_configuration = actions_configuration
|
19
|
+
end
|
20
|
+
|
21
|
+
private
|
22
|
+
|
23
|
+
attr_accessor :workflow
|
24
|
+
|
25
|
+
attr_reader :actions_configuration
|
26
|
+
|
27
|
+
def actions_configuration=(input)
|
28
|
+
@actions_configuration = Array.wrap(input)
|
29
|
+
end
|
30
|
+
|
31
|
+
public
|
32
|
+
|
33
|
+
def call
|
34
|
+
generate_state_diagram!
|
35
|
+
workflow
|
36
|
+
end
|
37
|
+
|
38
|
+
private
|
39
|
+
|
40
|
+
def generate_state_diagram!
|
41
|
+
actions_configuration.each do |configuration|
|
42
|
+
Array.wrap(configuration.fetch(:name)).each do |name|
|
43
|
+
StateMachineGenerator.generate_from_schema(workflow: workflow, name: name, **configuration.except(:name))
|
44
|
+
end
|
45
|
+
end
|
46
|
+
end
|
47
|
+
end
|
48
|
+
end
|
49
|
+
end
|
@@ -0,0 +1,102 @@
|
|
1
|
+
module CurationConcerns
|
2
|
+
module Workflow
|
3
|
+
# Imports a single action for a workflow, including all of the adjacent states,
|
4
|
+
# permissions and notifications
|
5
|
+
class StateMachineGenerator
|
6
|
+
def self.generate_from_schema(workflow:, name:, **keywords)
|
7
|
+
new(
|
8
|
+
workflow: workflow, action_name: name, config: keywords,
|
9
|
+
email_generator_method_name: :schema_based_email_generator_method
|
10
|
+
).call
|
11
|
+
end
|
12
|
+
|
13
|
+
def initialize(workflow:, action_name:, config:, email_generator_method_name: :schema_based_email_generator_method)
|
14
|
+
self.workflow = workflow
|
15
|
+
self.action_name = action_name
|
16
|
+
self.config = config
|
17
|
+
self.email_generator_method_name = email_generator_method_name
|
18
|
+
end
|
19
|
+
|
20
|
+
private
|
21
|
+
|
22
|
+
attr_accessor :workflow, :action_name, :config, :email_generator_method_name
|
23
|
+
|
24
|
+
def create_workflow_action!
|
25
|
+
@action = Sipity::WorkflowAction.find_or_create_by!(workflow: workflow, name: action_name.to_s)
|
26
|
+
end
|
27
|
+
|
28
|
+
public
|
29
|
+
|
30
|
+
attr_reader :action
|
31
|
+
|
32
|
+
def call
|
33
|
+
create_workflow_action!
|
34
|
+
|
35
|
+
if config.key?(:attributes)
|
36
|
+
build_attributes(config.fetch(:attributes).stringify_keys)
|
37
|
+
end
|
38
|
+
|
39
|
+
# Strategy State
|
40
|
+
config.fetch(:from_states, []).each do |entry|
|
41
|
+
build_from_state(entry.fetch(:names), entry.fetch(:roles))
|
42
|
+
end
|
43
|
+
|
44
|
+
# Transitions
|
45
|
+
if config.key?(:transition_to)
|
46
|
+
build_transitions(config.fetch(:transition_to).to_s)
|
47
|
+
end
|
48
|
+
|
49
|
+
send(email_generator_method_name, workflow: workflow, config: config)
|
50
|
+
|
51
|
+
# Methods
|
52
|
+
if config.key?(:methods)
|
53
|
+
build_methods(Array.wrap(config.fetch(:methods)))
|
54
|
+
end
|
55
|
+
end
|
56
|
+
|
57
|
+
def build_attributes(action_attributes)
|
58
|
+
action_attributes.delete('presentation_sequence') # TODO: remove this line when we want to support presentation_sequence
|
59
|
+
existing_action_attributes = action.attributes.slice(*action_attributes.keys)
|
60
|
+
unless action_attributes == existing_action_attributes
|
61
|
+
action.update_attributes!(action_attributes)
|
62
|
+
end
|
63
|
+
end
|
64
|
+
|
65
|
+
def build_transitions(name)
|
66
|
+
transition_to_state = Sipity::WorkflowState.find_or_create_by!(workflow: workflow, name: name)
|
67
|
+
if action.resulting_workflow_state != transition_to_state
|
68
|
+
action.resulting_workflow_state = transition_to_state
|
69
|
+
action.save!
|
70
|
+
end
|
71
|
+
end
|
72
|
+
|
73
|
+
# @params state_names[Array]
|
74
|
+
# @params roles [Array]
|
75
|
+
def build_from_state(state_names, state_roles)
|
76
|
+
Array.wrap(state_names).each do |state_name|
|
77
|
+
workflow_state = Sipity::WorkflowState.find_or_create_by!(workflow: workflow, name: state_name.to_s)
|
78
|
+
PermissionGenerator.call(
|
79
|
+
actors: [],
|
80
|
+
roles: state_roles,
|
81
|
+
workflow_state: workflow_state,
|
82
|
+
action_names: action_name,
|
83
|
+
workflow: workflow
|
84
|
+
)
|
85
|
+
end
|
86
|
+
end
|
87
|
+
|
88
|
+
def build_methods(method_list)
|
89
|
+
MethodGenerator.call(action: action, list: method_list)
|
90
|
+
end
|
91
|
+
|
92
|
+
def schema_based_email_generator_method(workflow:, config:)
|
93
|
+
Array.wrap(config.fetch(:notifications, [])).each do |configuration|
|
94
|
+
notification_configuration = NotificationConfigurationParameter.build_from_workflow_action_configuration(
|
95
|
+
workflow_action: action_name, config: configuration
|
96
|
+
)
|
97
|
+
NotificationGenerator.call(workflow: workflow, notification_configuration: notification_configuration)
|
98
|
+
end
|
99
|
+
end
|
100
|
+
end
|
101
|
+
end
|
102
|
+
end
|
@@ -0,0 +1,52 @@
|
|
1
|
+
module CurationConcerns
|
2
|
+
module Workflow
|
3
|
+
class StatusListService
|
4
|
+
# @param user [User]
|
5
|
+
def initialize(user)
|
6
|
+
@user = user
|
7
|
+
end
|
8
|
+
|
9
|
+
attr_reader :user
|
10
|
+
|
11
|
+
# TODO: We will want to paginate this
|
12
|
+
# @return [Array<StatusRow>] a list of results that the given user can take action on.
|
13
|
+
def each
|
14
|
+
return enum_for(:each) unless block_given?
|
15
|
+
solr_documents.each do |doc|
|
16
|
+
yield doc
|
17
|
+
end
|
18
|
+
end
|
19
|
+
|
20
|
+
private
|
21
|
+
|
22
|
+
# @return [Hash<String,SolrDocument>] a hash of id to solr document
|
23
|
+
def solr_documents
|
24
|
+
search_solr.map { |result| SolrDocument.new(result) }
|
25
|
+
end
|
26
|
+
|
27
|
+
def search_solr
|
28
|
+
actionable_roles = roles_for_user
|
29
|
+
return [] if actionable_roles.empty?
|
30
|
+
WorkRelation.new.search_with_conditions(
|
31
|
+
{ actionable_workflow_roles_ssim: actionable_roles },
|
32
|
+
fl: 'id title_tesim has_model_ssim, workflow_state_name_ssim',
|
33
|
+
rows: 1000)
|
34
|
+
end
|
35
|
+
|
36
|
+
# @return [Array<String>] the list of workflow-role combinations this user has
|
37
|
+
def roles_for_user
|
38
|
+
Sipity::Workflow.all.flat_map do |wf|
|
39
|
+
workflow_roles_for_user_and_workflow(wf).map do |wf_role|
|
40
|
+
"#{wf.name}-#{wf_role.role.name}"
|
41
|
+
end
|
42
|
+
end
|
43
|
+
end
|
44
|
+
|
45
|
+
# @param workflow [Sipity::Workflow]
|
46
|
+
# @return [ActiveRecord::Relation<Sipity::WorkflowRole>]
|
47
|
+
def workflow_roles_for_user_and_workflow(workflow)
|
48
|
+
CurationConcerns::Workflow::PermissionQuery.scope_processing_workflow_roles_for_user_and_workflow(user: user, workflow: workflow)
|
49
|
+
end
|
50
|
+
end
|
51
|
+
end
|
52
|
+
end
|