NEMO-CE 7.3.6__tar.gz → 7.3.7__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.
Files changed (603) hide show
  1. {nemo_ce-7.3.6 → nemo_ce-7.3.7}/NEMO/admin.py +12 -1
  2. nemo_ce-7.3.7/NEMO/migrations/0141_toolqualificationexpiration.py +103 -0
  3. {nemo_ce-7.3.6 → nemo_ce-7.3.7}/NEMO/models.py +81 -15
  4. {nemo_ce-7.3.6 → nemo_ce-7.3.7}/NEMO/templates/customizations/customizations_tool.html +5 -88
  5. {nemo_ce-7.3.6 → nemo_ce-7.3.7}/NEMO/templates/tool_control/tool_status.html +2 -2
  6. {nemo_ce-7.3.6 → nemo_ce-7.3.7}/NEMO/templates/tool_control/usage_data.html +46 -6
  7. {nemo_ce-7.3.6 → nemo_ce-7.3.7}/NEMO/tests/test_tools/test_tool_qualification_expiration.py +40 -30
  8. {nemo_ce-7.3.6 → nemo_ce-7.3.7}/NEMO/views/api.py +6 -1
  9. {nemo_ce-7.3.6 → nemo_ce-7.3.7}/NEMO/views/calendar.py +2 -3
  10. {nemo_ce-7.3.6 → nemo_ce-7.3.7}/NEMO/views/customization.py +1 -9
  11. {nemo_ce-7.3.6 → nemo_ce-7.3.7}/NEMO/views/timed_services.py +37 -28
  12. {nemo_ce-7.3.6 → nemo_ce-7.3.7}/NEMO/views/tool_control.py +52 -24
  13. {nemo_ce-7.3.6 → nemo_ce-7.3.7}/NEMO_CE.egg-info/PKG-INFO +1 -1
  14. {nemo_ce-7.3.6 → nemo_ce-7.3.7}/NEMO_CE.egg-info/SOURCES.txt +1 -0
  15. {nemo_ce-7.3.6 → nemo_ce-7.3.7}/PKG-INFO +1 -1
  16. {nemo_ce-7.3.6 → nemo_ce-7.3.7}/pyproject.toml +1 -1
  17. {nemo_ce-7.3.6 → nemo_ce-7.3.7}/LICENSE +0 -0
  18. {nemo_ce-7.3.6 → nemo_ce-7.3.7}/NEMO/__init__.py +0 -0
  19. {nemo_ce-7.3.6 → nemo_ce-7.3.7}/NEMO/actions.py +0 -0
  20. {nemo_ce-7.3.6 → nemo_ce-7.3.7}/NEMO/apps/__init__.py +0 -0
  21. {nemo_ce-7.3.6 → nemo_ce-7.3.7}/NEMO/apps/area_access/__init__.py +0 -0
  22. {nemo_ce-7.3.6 → nemo_ce-7.3.7}/NEMO/apps/area_access/apps.py +0 -0
  23. {nemo_ce-7.3.6 → nemo_ce-7.3.7}/NEMO/apps/area_access/static/area_access/area_access.css +0 -0
  24. {nemo_ce-7.3.6 → nemo_ce-7.3.7}/NEMO/apps/area_access/templates/area_access/already_logged_in.html +0 -0
  25. {nemo_ce-7.3.6 → nemo_ce-7.3.7}/NEMO/apps/area_access/templates/area_access/badge_not_found.html +0 -0
  26. {nemo_ce-7.3.6 → nemo_ce-7.3.7}/NEMO/apps/area_access/templates/area_access/base.html +0 -0
  27. {nemo_ce-7.3.6 → nemo_ce-7.3.7}/NEMO/apps/area_access/templates/area_access/choose_area.html +0 -0
  28. {nemo_ce-7.3.6 → nemo_ce-7.3.7}/NEMO/apps/area_access/templates/area_access/choose_project.html +0 -0
  29. {nemo_ce-7.3.6 → nemo_ce-7.3.7}/NEMO/apps/area_access/templates/area_access/door_is_open.html +0 -0
  30. {nemo_ce-7.3.6 → nemo_ce-7.3.7}/NEMO/apps/area_access/templates/area_access/farewell_screen.html +0 -0
  31. {nemo_ce-7.3.6 → nemo_ce-7.3.7}/NEMO/apps/area_access/templates/area_access/inactive.html +0 -0
  32. {nemo_ce-7.3.6 → nemo_ce-7.3.7}/NEMO/apps/area_access/templates/area_access/login_success.html +0 -0
  33. {nemo_ce-7.3.6 → nemo_ce-7.3.7}/NEMO/apps/area_access/templates/area_access/logout_success.html +0 -0
  34. {nemo_ce-7.3.6 → nemo_ce-7.3.7}/NEMO/apps/area_access/templates/area_access/logout_warning.html +0 -0
  35. {nemo_ce-7.3.6 → nemo_ce-7.3.7}/NEMO/apps/area_access/templates/area_access/no_active_projects.html +0 -0
  36. {nemo_ce-7.3.6 → nemo_ce-7.3.7}/NEMO/apps/area_access/templates/area_access/not_logged_in.html +0 -0
  37. {nemo_ce-7.3.6 → nemo_ce-7.3.7}/NEMO/apps/area_access/templates/area_access/physical_access_denied.html +0 -0
  38. {nemo_ce-7.3.6 → nemo_ce-7.3.7}/NEMO/apps/area_access/templates/area_access/resource_unavailable.html +0 -0
  39. {nemo_ce-7.3.6 → nemo_ce-7.3.7}/NEMO/apps/area_access/templates/area_access/welcome_screen.html +0 -0
  40. {nemo_ce-7.3.6 → nemo_ce-7.3.7}/NEMO/apps/area_access/urls.py +0 -0
  41. {nemo_ce-7.3.6 → nemo_ce-7.3.7}/NEMO/apps/area_access/views.py +0 -0
  42. {nemo_ce-7.3.6 → nemo_ce-7.3.7}/NEMO/apps/kiosk/__init__.py +0 -0
  43. {nemo_ce-7.3.6 → nemo_ce-7.3.7}/NEMO/apps/kiosk/apps.py +0 -0
  44. {nemo_ce-7.3.6 → nemo_ce-7.3.7}/NEMO/apps/kiosk/static/kiosk/kiosk.css +0 -0
  45. {nemo_ce-7.3.6 → nemo_ce-7.3.7}/NEMO/apps/kiosk/templates/kiosk/acknowledgement.html +0 -0
  46. {nemo_ce-7.3.6 → nemo_ce-7.3.7}/NEMO/apps/kiosk/templates/kiosk/category_choices.html +0 -0
  47. {nemo_ce-7.3.6 → nemo_ce-7.3.7}/NEMO/apps/kiosk/templates/kiosk/choices.html +0 -0
  48. {nemo_ce-7.3.6 → nemo_ce-7.3.7}/NEMO/apps/kiosk/templates/kiosk/consumables.html +0 -0
  49. {nemo_ce-7.3.6 → nemo_ce-7.3.7}/NEMO/apps/kiosk/templates/kiosk/consumables_order.html +0 -0
  50. {nemo_ce-7.3.6 → nemo_ce-7.3.7}/NEMO/apps/kiosk/templates/kiosk/error.html +0 -0
  51. {nemo_ce-7.3.6 → nemo_ce-7.3.7}/NEMO/apps/kiosk/templates/kiosk/individual_reservation.html +0 -0
  52. {nemo_ce-7.3.6 → nemo_ce-7.3.7}/NEMO/apps/kiosk/templates/kiosk/kiosk.html +0 -0
  53. {nemo_ce-7.3.6 → nemo_ce-7.3.7}/NEMO/apps/kiosk/templates/kiosk/success.html +0 -0
  54. {nemo_ce-7.3.6 → nemo_ce-7.3.7}/NEMO/apps/kiosk/templates/kiosk/tool_categories.html +0 -0
  55. {nemo_ce-7.3.6 → nemo_ce-7.3.7}/NEMO/apps/kiosk/templates/kiosk/tool_information.html +0 -0
  56. {nemo_ce-7.3.6 → nemo_ce-7.3.7}/NEMO/apps/kiosk/templates/kiosk/tool_post_comment.html +0 -0
  57. {nemo_ce-7.3.6 → nemo_ce-7.3.7}/NEMO/apps/kiosk/templates/kiosk/tool_project_selection_snippet.html +0 -0
  58. {nemo_ce-7.3.6 → nemo_ce-7.3.7}/NEMO/apps/kiosk/templates/kiosk/tool_report_problem.html +0 -0
  59. {nemo_ce-7.3.6 → nemo_ce-7.3.7}/NEMO/apps/kiosk/templates/kiosk/tool_reservation.html +0 -0
  60. {nemo_ce-7.3.6 → nemo_ce-7.3.7}/NEMO/apps/kiosk/templates/kiosk/tool_reservation_extra.html +0 -0
  61. {nemo_ce-7.3.6 → nemo_ce-7.3.7}/NEMO/apps/kiosk/urls.py +0 -0
  62. {nemo_ce-7.3.6 → nemo_ce-7.3.7}/NEMO/apps/kiosk/views.py +0 -0
  63. {nemo_ce-7.3.6 → nemo_ce-7.3.7}/NEMO/apps/nemo_ce/__init__.py +0 -0
  64. {nemo_ce-7.3.6 → nemo_ce-7.3.7}/NEMO/apps/nemo_ce/management/__init__.py +0 -0
  65. {nemo_ce-7.3.6 → nemo_ce-7.3.7}/NEMO/apps/nemo_ce/management/commands/__init__.py +0 -0
  66. {nemo_ce-7.3.6 → nemo_ce-7.3.7}/NEMO/apps/nemo_ce/management/commands/makemigrations.py +0 -0
  67. {nemo_ce-7.3.6 → nemo_ce-7.3.7}/NEMO/apps/nemo_ce/migration_utils.py +0 -0
  68. {nemo_ce-7.3.6 → nemo_ce-7.3.7}/NEMO/apps/nemo_ce/migrations/0001_ce_tool_accessories.py +0 -0
  69. {nemo_ce-7.3.6 → nemo_ce-7.3.7}/NEMO/apps/nemo_ce/migrations/0002_ce_tool_reservation_required.py +0 -0
  70. {nemo_ce-7.3.6 → nemo_ce-7.3.7}/NEMO/apps/nemo_ce/migrations/0003_ce_training_module.py +0 -0
  71. {nemo_ce-7.3.6 → nemo_ce-7.3.7}/NEMO/apps/nemo_ce/migrations/0004_ce_qualification_levels.py +0 -0
  72. {nemo_ce-7.3.6 → nemo_ce-7.3.7}/NEMO/apps/nemo_ce/migrations/0005_ce_add_project_to_training_request.py +0 -0
  73. {nemo_ce-7.3.6 → nemo_ce-7.3.7}/NEMO/apps/nemo_ce/migrations/0006_ce_qualification_history_in_training.py +0 -0
  74. {nemo_ce-7.3.6 → nemo_ce-7.3.7}/NEMO/apps/nemo_ce/migrations/0007_ce_recording_training_events.py +0 -0
  75. {nemo_ce-7.3.6 → nemo_ce-7.3.7}/NEMO/apps/nemo_ce/migrations/0008_ce_qualification_level_in_training_history.py +0 -0
  76. {nemo_ce-7.3.6 → nemo_ce-7.3.7}/NEMO/apps/nemo_ce/migrations/0009_ce_add_tool_grant_qualification_levels.py +0 -0
  77. {nemo_ce-7.3.6 → nemo_ce-7.3.7}/NEMO/apps/nemo_ce/migrations/0010_ce_add_invitation_only_training.py +0 -0
  78. {nemo_ce-7.3.6 → nemo_ce-7.3.7}/NEMO/apps/nemo_ce/migrations/0011_ce_shadowing_verification.py +0 -0
  79. {nemo_ce-7.3.6 → nemo_ce-7.3.7}/NEMO/apps/nemo_ce/migrations/0012_ce_notification_types_update.py +0 -0
  80. {nemo_ce-7.3.6 → nemo_ce-7.3.7}/NEMO/apps/nemo_ce/migrations/0013_ce_shadowing_reviewers_in_tool.py +0 -0
  81. {nemo_ce-7.3.6 → nemo_ce-7.3.7}/NEMO/apps/nemo_ce/migrations/0014_ce_remove_default_value_tool_shadowing.py +0 -0
  82. {nemo_ce-7.3.6 → nemo_ce-7.3.7}/NEMO/apps/nemo_ce/migrations/0015_ce_precursor_configurations.py +0 -0
  83. {nemo_ce-7.3.6 → nemo_ce-7.3.7}/NEMO/apps/nemo_ce/migrations/0016_ce_precursor_config_allow_duplicates.py +0 -0
  84. {nemo_ce-7.3.6 → nemo_ce-7.3.7}/NEMO/apps/nemo_ce/migrations/0017_ce_training_request_message.py +0 -0
  85. {nemo_ce-7.3.6 → nemo_ce-7.3.7}/NEMO/apps/nemo_ce/migrations/0018_ce_training_qualification.py +0 -0
  86. {nemo_ce-7.3.6 → nemo_ce-7.3.7}/NEMO/apps/nemo_ce/migrations/0019_tool_training_details_without_area_access.py +0 -0
  87. {nemo_ce-7.3.6 → nemo_ce-7.3.7}/NEMO/apps/nemo_ce/migrations/0020_training_events_auto_cancel.py +0 -0
  88. {nemo_ce-7.3.6 → nemo_ce-7.3.7}/NEMO/apps/nemo_ce/migrations/0021_ce_tool_logout_grace_period.py +0 -0
  89. {nemo_ce-7.3.6 → nemo_ce-7.3.7}/NEMO/apps/nemo_ce/migrations/0022_ce_training_technique_description.py +0 -0
  90. {nemo_ce-7.3.6 → nemo_ce-7.3.7}/NEMO/apps/nemo_ce/migrations/0023_ce_training_qualification_levels.py +0 -0
  91. {nemo_ce-7.3.6 → nemo_ce-7.3.7}/NEMO/apps/nemo_ce/migrations/0024_ce_training_location.py +0 -0
  92. {nemo_ce-7.3.6 → nemo_ce-7.3.7}/NEMO/apps/nemo_ce/migrations/0025_ce_charfield_max_length_constants.py +0 -0
  93. {nemo_ce-7.3.6 → nemo_ce-7.3.7}/NEMO/apps/nemo_ce/migrations/0026_ce_qualification_level_fulfill_training_option.py +0 -0
  94. {nemo_ce-7.3.6 → nemo_ce-7.3.7}/NEMO/apps/nemo_ce/migrations/0027_ce_qualification_level_during_closures.py +0 -0
  95. {nemo_ce-7.3.6 → nemo_ce-7.3.7}/NEMO/apps/nemo_ce/migrations/__init__.py +0 -0
  96. {nemo_ce-7.3.6 → nemo_ce-7.3.7}/NEMO/constants.py +0 -0
  97. {nemo_ce-7.3.6 → nemo_ce-7.3.7}/NEMO/context_processors.py +0 -0
  98. {nemo_ce-7.3.6 → nemo_ce-7.3.7}/NEMO/decorators.py +0 -0
  99. {nemo_ce-7.3.6 → nemo_ce-7.3.7}/NEMO/evaluators.py +0 -0
  100. {nemo_ce-7.3.6 → nemo_ce-7.3.7}/NEMO/exceptions.py +0 -0
  101. {nemo_ce-7.3.6 → nemo_ce-7.3.7}/NEMO/fields.py +0 -0
  102. {nemo_ce-7.3.6 → nemo_ce-7.3.7}/NEMO/forms.py +0 -0
  103. {nemo_ce-7.3.6 → nemo_ce-7.3.7}/NEMO/interlocks.py +0 -0
  104. {nemo_ce-7.3.6 → nemo_ce-7.3.7}/NEMO/log.py +0 -0
  105. {nemo_ce-7.3.6 → nemo_ce-7.3.7}/NEMO/management/__init__.py +0 -0
  106. {nemo_ce-7.3.6 → nemo_ce-7.3.7}/NEMO/management/commands/__init__.py +0 -0
  107. {nemo_ce-7.3.6 → nemo_ce-7.3.7}/NEMO/management/commands/area_auto_logout_users.py +0 -0
  108. {nemo_ce-7.3.6 → nemo_ce-7.3.7}/NEMO/management/commands/auto_cancel_training_sessions.py +0 -0
  109. {nemo_ce-7.3.6 → nemo_ce-7.3.7}/NEMO/management/commands/auto_validate_charges.py +0 -0
  110. {nemo_ce-7.3.6 → nemo_ce-7.3.7}/NEMO/management/commands/cancel_unused_reservations.py +0 -0
  111. {nemo_ce-7.3.6 → nemo_ce-7.3.7}/NEMO/management/commands/check_and_update_wait_list.py +0 -0
  112. {nemo_ce-7.3.6 → nemo_ce-7.3.7}/NEMO/management/commands/create_closure_alerts.py +0 -0
  113. {nemo_ce-7.3.6 → nemo_ce-7.3.7}/NEMO/management/commands/deactivate_access_expired_users.py +0 -0
  114. {nemo_ce-7.3.6 → nemo_ce-7.3.7}/NEMO/management/commands/manage_recurring_charges.py +0 -0
  115. {nemo_ce-7.3.6 → nemo_ce-7.3.7}/NEMO/management/commands/manage_tool_qualifications.py +0 -0
  116. {nemo_ce-7.3.6 → nemo_ce-7.3.7}/NEMO/management/commands/send_email_grant_access.py +0 -0
  117. {nemo_ce-7.3.6 → nemo_ce-7.3.7}/NEMO/management/commands/send_email_interlock_usage_report.py +0 -0
  118. {nemo_ce-7.3.6 → nemo_ce-7.3.7}/NEMO/management/commands/send_email_out_of_time_reservation_notification.py +0 -0
  119. {nemo_ce-7.3.6 → nemo_ce-7.3.7}/NEMO/management/commands/send_email_reservation_ending_reminders.py +0 -0
  120. {nemo_ce-7.3.6 → nemo_ce-7.3.7}/NEMO/management/commands/send_email_reservation_reminders.py +0 -0
  121. {nemo_ce-7.3.6 → nemo_ce-7.3.7}/NEMO/management/commands/send_email_scheduled_outage_reminders.py +0 -0
  122. {nemo_ce-7.3.6 → nemo_ce-7.3.7}/NEMO/management/commands/send_email_usage_reminders.py +0 -0
  123. {nemo_ce-7.3.6 → nemo_ce-7.3.7}/NEMO/management/commands/send_email_user_access_expiration_reminders.py +0 -0
  124. {nemo_ce-7.3.6 → nemo_ce-7.3.7}/NEMO/management/commands/send_email_weekend_access_notification.py +0 -0
  125. {nemo_ce-7.3.6 → nemo_ce-7.3.7}/NEMO/middleware.py +0 -0
  126. {nemo_ce-7.3.6 → nemo_ce-7.3.7}/NEMO/migrations/0001_version_1_0_0.py +0 -0
  127. {nemo_ce-7.3.6 → nemo_ce-7.3.7}/NEMO/migrations/0002_version_1_0_0_squashed.py +0 -0
  128. {nemo_ce-7.3.6 → nemo_ce-7.3.7}/NEMO/migrations/0012_version_2_0_0_squashed.py +0 -0
  129. {nemo_ce-7.3.6 → nemo_ce-7.3.7}/NEMO/migrations/0020_version_3_0_0_squashed.py +0 -0
  130. {nemo_ce-7.3.6 → nemo_ce-7.3.7}/NEMO/migrations/0038_version_4_0_0_squashed.py +0 -0
  131. {nemo_ce-7.3.6 → nemo_ce-7.3.7}/NEMO/migrations/0055_reservationconfigurationoption.py +0 -0
  132. {nemo_ce-7.3.6 → nemo_ce-7.3.7}/NEMO/migrations/0056_version_5_2_0.py +0 -0
  133. {nemo_ce-7.3.6 → nemo_ce-7.3.7}/NEMO/migrations/0057_version_5_3_0.py +0 -0
  134. {nemo_ce-7.3.6 → nemo_ce-7.3.7}/NEMO/migrations/0058_reservation_confirmation_override_prefs.py +0 -0
  135. {nemo_ce-7.3.6 → nemo_ce-7.3.7}/NEMO/migrations/0059_tool_pre_usage_questions.py +0 -0
  136. {nemo_ce-7.3.6 → nemo_ce-7.3.7}/NEMO/migrations/0060_add_impersonate_permission.py +0 -0
  137. {nemo_ce-7.3.6 → nemo_ce-7.3.7}/NEMO/migrations/0061_alter_interlock_unique_together.py +0 -0
  138. {nemo_ce-7.3.6 → nemo_ce-7.3.7}/NEMO/migrations/0062_migrate_email_upcoming_reservation.py +0 -0
  139. {nemo_ce-7.3.6 → nemo_ce-7.3.7}/NEMO/migrations/0063_knowledge_base.py +0 -0
  140. {nemo_ce-7.3.6 → nemo_ce-7.3.7}/NEMO/migrations/0064_consumable_self_checkout_only_users.py +0 -0
  141. {nemo_ce-7.3.6 → nemo_ce-7.3.7}/NEMO/migrations/0065_door_adjacent_area.py +0 -0
  142. {nemo_ce-7.3.6 → nemo_ce-7.3.7}/NEMO/migrations/0066_tool_ask_to_leave_area_when_done_using.py +0 -0
  143. {nemo_ce-7.3.6 → nemo_ce-7.3.7}/NEMO/migrations/0067_project_allow_staff_charges.py +0 -0
  144. {nemo_ce-7.3.6 → nemo_ce-7.3.7}/NEMO/migrations/0068_door_multiple_areas.py +0 -0
  145. {nemo_ce-7.3.6 → nemo_ce-7.3.7}/NEMO/migrations/0069_version_5_5_0.py +0 -0
  146. {nemo_ce-7.3.6 → nemo_ce-7.3.7}/NEMO/migrations/0070_calendar_axis_time_format_rename.py +0 -0
  147. {nemo_ce-7.3.6 → nemo_ce-7.3.7}/NEMO/migrations/0071_wait_list.py +0 -0
  148. {nemo_ce-7.3.6 → nemo_ce-7.3.7}/NEMO/migrations/0072_documents_display_order.py +0 -0
  149. {nemo_ce-7.3.6 → nemo_ce-7.3.7}/NEMO/migrations/0073_knowledge_safety_items_display_order.py +0 -0
  150. {nemo_ce-7.3.6 → nemo_ce-7.3.7}/NEMO/migrations/0074_scheduled_outage_reminders.py +0 -0
  151. {nemo_ce-7.3.6 → nemo_ce-7.3.7}/NEMO/migrations/0075_adjustmentrequest_applied.py +0 -0
  152. {nemo_ce-7.3.6 → nemo_ce-7.3.7}/NEMO/migrations/0076_default_display_order.py +0 -0
  153. {nemo_ce-7.3.6 → nemo_ce-7.3.7}/NEMO/migrations/0077_interlock_name.py +0 -0
  154. {nemo_ce-7.3.6 → nemo_ce-7.3.7}/NEMO/migrations/0078_version_5_6_0.py +0 -0
  155. {nemo_ce-7.3.6 → nemo_ce-7.3.7}/NEMO/migrations/0079_user_active_access_expiration_verbose_names.py +0 -0
  156. {nemo_ce-7.3.6 → nemo_ce-7.3.7}/NEMO/migrations/0080_version_6_0_0.py +0 -0
  157. {nemo_ce-7.3.6 → nemo_ce-7.3.7}/NEMO/migrations/0081_oracle_django_4_rename.py +0 -0
  158. {nemo_ce-7.3.6 → nemo_ce-7.3.7}/NEMO/migrations/0082_alter_userpreferences_tool_task_notifications.py +0 -0
  159. {nemo_ce-7.3.6 → nemo_ce-7.3.7}/NEMO/migrations/0083_toolcredentials.py +0 -0
  160. {nemo_ce-7.3.6 → nemo_ce-7.3.7}/NEMO/migrations/0084_remove_tool__allow_delayed_logoff_and_more.py +0 -0
  161. {nemo_ce-7.3.6 → nemo_ce-7.3.7}/NEMO/migrations/0085_contactinformation_title_and_more.py +0 -0
  162. {nemo_ce-7.3.6 → nemo_ce-7.3.7}/NEMO/migrations/0086_adjustmentrequest_new_quantity.py +0 -0
  163. {nemo_ce-7.3.6 → nemo_ce-7.3.7}/NEMO/migrations/0087_version_7_0_0.py +0 -0
  164. {nemo_ce-7.3.6 → nemo_ce-7.3.7}/NEMO/migrations/0088_alter_configurationoption_options.py +0 -0
  165. {nemo_ce-7.3.6 → nemo_ce-7.3.7}/NEMO/migrations/0089_door_farewell_message.py +0 -0
  166. {nemo_ce-7.3.6 → nemo_ce-7.3.7}/NEMO/migrations/0090_toolusagecounter_counter_direction_and_more.py +0 -0
  167. {nemo_ce-7.3.6 → nemo_ce-7.3.7}/NEMO/migrations/0091_adjustmentrequest_waive_charges.py +0 -0
  168. {nemo_ce-7.3.6 → nemo_ce-7.3.7}/NEMO/migrations/0092_alter_accounttype_name_alter_alert_category_and_more.py +0 -0
  169. {nemo_ce-7.3.6 → nemo_ce-7.3.7}/NEMO/migrations/0093_trainingsession_usage_event_usageevent_training.py +0 -0
  170. {nemo_ce-7.3.6 → nemo_ce-7.3.7}/NEMO/migrations/0094_interlockcard_extra_args.py +0 -0
  171. {nemo_ce-7.3.6 → nemo_ce-7.3.7}/NEMO/migrations/0095_reservationquestions_enabled.py +0 -0
  172. {nemo_ce-7.3.6 → nemo_ce-7.3.7}/NEMO/migrations/0096_alter_landingpagechoice_notifications_and_more.py +0 -0
  173. {nemo_ce-7.3.6 → nemo_ce-7.3.7}/NEMO/migrations/0097_fundtype_project_fund_types.py +0 -0
  174. {nemo_ce-7.3.6 → nemo_ce-7.3.7}/NEMO/migrations/0098_tool_area_maximum_future_reservations.py +0 -0
  175. {nemo_ce-7.3.6 → nemo_ce-7.3.7}/NEMO/migrations/0099_rename_fundtype_projecttype_and_more.py +0 -0
  176. {nemo_ce-7.3.6 → nemo_ce-7.3.7}/NEMO/migrations/0100_staff_assistance_requests.py +0 -0
  177. {nemo_ce-7.3.6 → nemo_ce-7.3.7}/NEMO/migrations/0101_alter_emaillog_category.py +0 -0
  178. {nemo_ce-7.3.6 → nemo_ce-7.3.7}/NEMO/migrations/0102_version_7_0_1.py +0 -0
  179. {nemo_ce-7.3.6 → nemo_ce-7.3.7}/NEMO/migrations/0103_alter_projectdocuments_display_order_and_more.py +0 -0
  180. {nemo_ce-7.3.6 → nemo_ce-7.3.7}/NEMO/migrations/0104_version_7_0_2.py +0 -0
  181. {nemo_ce-7.3.6 → nemo_ce-7.3.7}/NEMO/migrations/0105_version_7_1_0.py +0 -0
  182. {nemo_ce-7.3.6 → nemo_ce-7.3.7}/NEMO/migrations/0106_toolusagecounter_tool_pre_post_usage_question.py +0 -0
  183. {nemo_ce-7.3.6 → nemo_ce-7.3.7}/NEMO/migrations/0107_customization_remote_work_on_behalf_update.py +0 -0
  184. {nemo_ce-7.3.6 → nemo_ce-7.3.7}/NEMO/migrations/0108_landingpagechoice_view_permission.py +0 -0
  185. {nemo_ce-7.3.6 → nemo_ce-7.3.7}/NEMO/migrations/0109_customization_area_logout_already_logged_in_update.py +0 -0
  186. {nemo_ce-7.3.6 → nemo_ce-7.3.7}/NEMO/migrations/0110_version_7_1_1.py +0 -0
  187. {nemo_ce-7.3.6 → nemo_ce-7.3.7}/NEMO/migrations/0111_version_7_1_3.py +0 -0
  188. {nemo_ce-7.3.6 → nemo_ce-7.3.7}/NEMO/migrations/0112_fix_project_name_uniqueness.py +0 -0
  189. {nemo_ce-7.3.6 → nemo_ce-7.3.7}/NEMO/migrations/0113_version_7_2_0.py +0 -0
  190. {nemo_ce-7.3.6 → nemo_ce-7.3.7}/NEMO/migrations/0114_alter_temporaryphysicalaccess_options_tool__staff.py +0 -0
  191. {nemo_ce-7.3.6 → nemo_ce-7.3.7}/NEMO/migrations/0115_tool__properties.py +0 -0
  192. {nemo_ce-7.3.6 → nemo_ce-7.3.7}/NEMO/migrations/0116_comment_pinned.py +0 -0
  193. {nemo_ce-7.3.6 → nemo_ce-7.3.7}/NEMO/migrations/0117_usageevent_has_ended.py +0 -0
  194. {nemo_ce-7.3.6 → nemo_ce-7.3.7}/NEMO/migrations/0118_areaaccessrecord_has_ended.py +0 -0
  195. {nemo_ce-7.3.6 → nemo_ce-7.3.7}/NEMO/migrations/0119_taskstatus_notify_tool_staff.py +0 -0
  196. {nemo_ce-7.3.6 → nemo_ce-7.3.7}/NEMO/migrations/0120_alter_userpreferences_options_and_more.py +0 -0
  197. {nemo_ce-7.3.6 → nemo_ce-7.3.7}/NEMO/migrations/0121_version_7_3_0.py +0 -0
  198. {nemo_ce-7.3.6 → nemo_ce-7.3.7}/NEMO/migrations/0122_user_managed_accounts.py +0 -0
  199. {nemo_ce-7.3.6 → nemo_ce-7.3.7}/NEMO/migrations/0123_account_note.py +0 -0
  200. {nemo_ce-7.3.6 → nemo_ce-7.3.7}/NEMO/migrations/0124_userpreferences_login_redirect_url.py +0 -0
  201. {nemo_ce-7.3.6 → nemo_ce-7.3.7}/NEMO/migrations/0125_alter_reservationquestions_name_toolusagequestions.py +0 -0
  202. {nemo_ce-7.3.6 → nemo_ce-7.3.7}/NEMO/migrations/0126_area_abuse_weight_tool__abuse_weight.py +0 -0
  203. {nemo_ce-7.3.6 → nemo_ce-7.3.7}/NEMO/migrations/0127_usercalendartoollist.py +0 -0
  204. {nemo_ce-7.3.6 → nemo_ce-7.3.7}/NEMO/migrations/0128_adjustmentrequest_new_project.py +0 -0
  205. {nemo_ce-7.3.6 → nemo_ce-7.3.7}/NEMO/migrations/0129_adjustmentrequest_original_end_and_more.py +0 -0
  206. {nemo_ce-7.3.6 → nemo_ce-7.3.7}/NEMO/migrations/0130_reservation_note_alter_tool__staff.py +0 -0
  207. {nemo_ce-7.3.6 → nemo_ce-7.3.7}/NEMO/migrations/0131_user_managed_users.py +0 -0
  208. {nemo_ce-7.3.6 → nemo_ce-7.3.7}/NEMO/migrations/0132_toolusagequestions_users_and_tools_and_more.py +0 -0
  209. {nemo_ce-7.3.6 → nemo_ce-7.3.7}/NEMO/migrations/0133_toolusagequestions_only_for_groups.py +0 -0
  210. {nemo_ce-7.3.6 → nemo_ce-7.3.7}/NEMO/migrations/0134_usageevent_note.py +0 -0
  211. {nemo_ce-7.3.6 → nemo_ce-7.3.7}/NEMO/migrations/0135_tool__problem_shutdown_enabled.py +0 -0
  212. {nemo_ce-7.3.6 → nemo_ce-7.3.7}/NEMO/migrations/0136_tool__requires_area_occupancy_minimum.py +0 -0
  213. {nemo_ce-7.3.6 → nemo_ce-7.3.7}/NEMO/migrations/0137_area_nemo_area_tree_id_lft_idx.py +0 -0
  214. {nemo_ce-7.3.6 → nemo_ce-7.3.7}/NEMO/migrations/0138_area_late_cancellation_reservation_threshold_and_more.py +0 -0
  215. {nemo_ce-7.3.6 → nemo_ce-7.3.7}/NEMO/migrations/0139_unplannedoutage.py +0 -0
  216. {nemo_ce-7.3.6 → nemo_ce-7.3.7}/NEMO/migrations/0140_alter_user_options.py +0 -0
  217. {nemo_ce-7.3.6 → nemo_ce-7.3.7}/NEMO/migrations/__init__.py +0 -0
  218. {nemo_ce-7.3.6 → nemo_ce-7.3.7}/NEMO/migrations_utils.py +0 -0
  219. {nemo_ce-7.3.6 → nemo_ce-7.3.7}/NEMO/mixins.py +0 -0
  220. {nemo_ce-7.3.6 → nemo_ce-7.3.7}/NEMO/model_tree.py +0 -0
  221. {nemo_ce-7.3.6 → nemo_ce-7.3.7}/NEMO/parsers.py +0 -0
  222. {nemo_ce-7.3.6 → nemo_ce-7.3.7}/NEMO/permissions.py +0 -0
  223. {nemo_ce-7.3.6 → nemo_ce-7.3.7}/NEMO/plugins/__init__.py +0 -0
  224. {nemo_ce-7.3.6 → nemo_ce-7.3.7}/NEMO/plugins/utils.py +0 -0
  225. {nemo_ce-7.3.6 → nemo_ce-7.3.7}/NEMO/policy.py +0 -0
  226. {nemo_ce-7.3.6 → nemo_ce-7.3.7}/NEMO/properties_schemas.py +0 -0
  227. {nemo_ce-7.3.6 → nemo_ce-7.3.7}/NEMO/provisioning.py +0 -0
  228. {nemo_ce-7.3.6 → nemo_ce-7.3.7}/NEMO/rates.py +0 -0
  229. {nemo_ce-7.3.6 → nemo_ce-7.3.7}/NEMO/rest_filter_backend.py +0 -0
  230. {nemo_ce-7.3.6 → nemo_ce-7.3.7}/NEMO/rest_pagination.py +0 -0
  231. {nemo_ce-7.3.6 → nemo_ce-7.3.7}/NEMO/serializers.py +0 -0
  232. {nemo_ce-7.3.6 → nemo_ce-7.3.7}/NEMO/static/admin/dynamic_form_preview/dynamic_form_preview.css +0 -0
  233. {nemo_ce-7.3.6 → nemo_ce-7.3.7}/NEMO/static/admin/dynamic_form_preview/dynamic_form_preview.js +0 -0
  234. {nemo_ce-7.3.6 → nemo_ce-7.3.7}/NEMO/static/admin/json_editor/jsoneditor-django.css +0 -0
  235. {nemo_ce-7.3.6 → nemo_ce-7.3.7}/NEMO/static/admin/json_editor/jsoneditor.min.js +0 -0
  236. {nemo_ce-7.3.6 → nemo_ce-7.3.7}/NEMO/static/admin/json_editor/jsoneditor_widget.js +0 -0
  237. {nemo_ce-7.3.6 → nemo_ce-7.3.7}/NEMO/static/admin/physical_access_level/access_level.js +0 -0
  238. {nemo_ce-7.3.6 → nemo_ce-7.3.7}/NEMO/static/admin/time_options_override.js +0 -0
  239. {nemo_ce-7.3.6 → nemo_ce-7.3.7}/NEMO/static/admin/tool/tool.js +0 -0
  240. {nemo_ce-7.3.6 → nemo_ce-7.3.7}/NEMO/static/badge_reader.js +0 -0
  241. {nemo_ce-7.3.6 → nemo_ce-7.3.7}/NEMO/static/bootstrap/css/bootstrap-theme.css +0 -0
  242. {nemo_ce-7.3.6 → nemo_ce-7.3.7}/NEMO/static/bootstrap/css/bootstrap-theme.css.map +0 -0
  243. {nemo_ce-7.3.6 → nemo_ce-7.3.7}/NEMO/static/bootstrap/css/bootstrap-theme.min.css +0 -0
  244. {nemo_ce-7.3.6 → nemo_ce-7.3.7}/NEMO/static/bootstrap/css/bootstrap.css +0 -0
  245. {nemo_ce-7.3.6 → nemo_ce-7.3.7}/NEMO/static/bootstrap/css/bootstrap.css.map +0 -0
  246. {nemo_ce-7.3.6 → nemo_ce-7.3.7}/NEMO/static/bootstrap/css/bootstrap.min.css +0 -0
  247. {nemo_ce-7.3.6 → nemo_ce-7.3.7}/NEMO/static/bootstrap/fonts/glyphicons-halflings-regular.eot +0 -0
  248. {nemo_ce-7.3.6 → nemo_ce-7.3.7}/NEMO/static/bootstrap/fonts/glyphicons-halflings-regular.svg +0 -0
  249. {nemo_ce-7.3.6 → nemo_ce-7.3.7}/NEMO/static/bootstrap/fonts/glyphicons-halflings-regular.ttf +0 -0
  250. {nemo_ce-7.3.6 → nemo_ce-7.3.7}/NEMO/static/bootstrap/fonts/glyphicons-halflings-regular.woff +0 -0
  251. {nemo_ce-7.3.6 → nemo_ce-7.3.7}/NEMO/static/bootstrap/fonts/glyphicons-halflings-regular.woff2 +0 -0
  252. {nemo_ce-7.3.6 → nemo_ce-7.3.7}/NEMO/static/bootstrap/js/bootstrap.js +0 -0
  253. {nemo_ce-7.3.6 → nemo_ce-7.3.7}/NEMO/static/bootstrap/js/bootstrap.min.js +0 -0
  254. {nemo_ce-7.3.6 → nemo_ce-7.3.7}/NEMO/static/datetimepicker/bootstrap-datetimepicker.css +0 -0
  255. {nemo_ce-7.3.6 → nemo_ce-7.3.7}/NEMO/static/datetimepicker/bootstrap-datetimepicker.js +0 -0
  256. {nemo_ce-7.3.6 → nemo_ce-7.3.7}/NEMO/static/favicon.ico +0 -0
  257. {nemo_ce-7.3.6 → nemo_ce-7.3.7}/NEMO/static/fullcalendar/fullcalendar.css +0 -0
  258. {nemo_ce-7.3.6 → nemo_ce-7.3.7}/NEMO/static/fullcalendar/fullcalendar.js +0 -0
  259. {nemo_ce-7.3.6 → nemo_ce-7.3.7}/NEMO/static/fullcalendar/fullcalendar.min.css +0 -0
  260. {nemo_ce-7.3.6 → nemo_ce-7.3.7}/NEMO/static/fullcalendar/fullcalendar.min.js +0 -0
  261. {nemo_ce-7.3.6 → nemo_ce-7.3.7}/NEMO/static/icons/agreement.png +0 -0
  262. {nemo_ce-7.3.6 → nemo_ce-7.3.7}/NEMO/static/icons/caution.png +0 -0
  263. {nemo_ce-7.3.6 → nemo_ce-7.3.7}/NEMO/static/icons/preferences.png +0 -0
  264. {nemo_ce-7.3.6 → nemo_ce-7.3.7}/NEMO/static/jquery.js +0 -0
  265. {nemo_ce-7.3.6 → nemo_ce-7.3.7}/NEMO/static/jquery.min.js +0 -0
  266. {nemo_ce-7.3.6 → nemo_ce-7.3.7}/NEMO/static/jumbotron_watermark.bmp +0 -0
  267. {nemo_ce-7.3.6 → nemo_ce-7.3.7}/NEMO/static/mobile.js +0 -0
  268. {nemo_ce-7.3.6 → nemo_ce-7.3.7}/NEMO/static/moment.js +0 -0
  269. {nemo_ce-7.3.6 → nemo_ce-7.3.7}/NEMO/static/moment.min.js +0 -0
  270. {nemo_ce-7.3.6 → nemo_ce-7.3.7}/NEMO/static/moment.min.js.map +0 -0
  271. {nemo_ce-7.3.6 → nemo_ce-7.3.7}/NEMO/static/nemo.css +0 -0
  272. {nemo_ce-7.3.6 → nemo_ce-7.3.7}/NEMO/static/nemo.js +0 -0
  273. {nemo_ce-7.3.6 → nemo_ce-7.3.7}/NEMO/static/numpad/custom_numpad.jquery.js +0 -0
  274. {nemo_ce-7.3.6 → nemo_ce-7.3.7}/NEMO/static/numpad/numpad.jquery.css +0 -0
  275. {nemo_ce-7.3.6 → nemo_ce-7.3.7}/NEMO/static/pickadate/default.css +0 -0
  276. {nemo_ce-7.3.6 → nemo_ce-7.3.7}/NEMO/static/pickadate/default.date.css +0 -0
  277. {nemo_ce-7.3.6 → nemo_ce-7.3.7}/NEMO/static/pickadate/default.time.css +0 -0
  278. {nemo_ce-7.3.6 → nemo_ce-7.3.7}/NEMO/static/pickadate/picker.date.js +0 -0
  279. {nemo_ce-7.3.6 → nemo_ce-7.3.7}/NEMO/static/pickadate/picker.js +0 -0
  280. {nemo_ce-7.3.6 → nemo_ce-7.3.7}/NEMO/static/pickadate/picker.time.js +0 -0
  281. {nemo_ce-7.3.6 → nemo_ce-7.3.7}/NEMO/static/robots.txt +0 -0
  282. {nemo_ce-7.3.6 → nemo_ce-7.3.7}/NEMO/static/select2/css/select2-bootstrap.css +0 -0
  283. {nemo_ce-7.3.6 → nemo_ce-7.3.7}/NEMO/static/select2/css/select2-bootstrap.min.css +0 -0
  284. {nemo_ce-7.3.6 → nemo_ce-7.3.7}/NEMO/static/select2/css/select2.css +0 -0
  285. {nemo_ce-7.3.6 → nemo_ce-7.3.7}/NEMO/static/select2/css/select2.min.css +0 -0
  286. {nemo_ce-7.3.6 → nemo_ce-7.3.7}/NEMO/static/select2/js/select2.js +0 -0
  287. {nemo_ce-7.3.6 → nemo_ce-7.3.7}/NEMO/static/select2/js/select2.min.js +0 -0
  288. {nemo_ce-7.3.6 → nemo_ce-7.3.7}/NEMO/static/typeahead.jquery.js +0 -0
  289. {nemo_ce-7.3.6 → nemo_ce-7.3.7}/NEMO/static/typeahead.jquery.min.js +0 -0
  290. {nemo_ce-7.3.6 → nemo_ce-7.3.7}/NEMO/static/virtualkeyboard/jquery.keyboard.js +0 -0
  291. {nemo_ce-7.3.6 → nemo_ce-7.3.7}/NEMO/static/virtualkeyboard/jquery.keyboard.min.js +0 -0
  292. {nemo_ce-7.3.6 → nemo_ce-7.3.7}/NEMO/static/virtualkeyboard/keyboard-basic.css +0 -0
  293. {nemo_ce-7.3.6 → nemo_ce-7.3.7}/NEMO/static/virtualkeyboard/keyboard-basic.min.css +0 -0
  294. {nemo_ce-7.3.6 → nemo_ce-7.3.7}/NEMO/templates/abuse/abuse.html +0 -0
  295. {nemo_ce-7.3.6 → nemo_ce-7.3.7}/NEMO/templates/abuse/user_drill_down.html +0 -0
  296. {nemo_ce-7.3.6 → nemo_ce-7.3.7}/NEMO/templates/accounts_and_projects/account_and_projects.html +0 -0
  297. {nemo_ce-7.3.6 → nemo_ce-7.3.7}/NEMO/templates/accounts_and_projects/accounts_and_projects.html +0 -0
  298. {nemo_ce-7.3.6 → nemo_ce-7.3.7}/NEMO/templates/accounts_and_projects/create_account.html +0 -0
  299. {nemo_ce-7.3.6 → nemo_ce-7.3.7}/NEMO/templates/accounts_and_projects/create_project.html +0 -0
  300. {nemo_ce-7.3.6 → nemo_ce-7.3.7}/NEMO/templates/accounts_and_projects/documents_for_project.html +0 -0
  301. {nemo_ce-7.3.6 → nemo_ce-7.3.7}/NEMO/templates/accounts_and_projects/project.html +0 -0
  302. {nemo_ce-7.3.6 → nemo_ce-7.3.7}/NEMO/templates/accounts_and_projects/projects.html +0 -0
  303. {nemo_ce-7.3.6 → nemo_ce-7.3.7}/NEMO/templates/accounts_and_projects/transfer_charges.html +0 -0
  304. {nemo_ce-7.3.6 → nemo_ce-7.3.7}/NEMO/templates/accounts_and_projects/users_for_project.html +0 -0
  305. {nemo_ce-7.3.6 → nemo_ce-7.3.7}/NEMO/templates/acknowledgement.html +0 -0
  306. {nemo_ce-7.3.6 → nemo_ce-7.3.7}/NEMO/templates/alerts.html +0 -0
  307. {nemo_ce-7.3.6 → nemo_ce-7.3.7}/NEMO/templates/area_access/area_access.html +0 -0
  308. {nemo_ce-7.3.6 → nemo_ce-7.3.7}/NEMO/templates/area_access/calendar_self_login.html +0 -0
  309. {nemo_ce-7.3.6 → nemo_ce-7.3.7}/NEMO/templates/area_access/change_project.html +0 -0
  310. {nemo_ce-7.3.6 → nemo_ce-7.3.7}/NEMO/templates/area_access/login_areas.html +0 -0
  311. {nemo_ce-7.3.6 → nemo_ce-7.3.7}/NEMO/templates/area_access/new_area_access_record.html +0 -0
  312. {nemo_ce-7.3.6 → nemo_ce-7.3.7}/NEMO/templates/area_access/new_area_access_record_details.html +0 -0
  313. {nemo_ce-7.3.6 → nemo_ce-7.3.7}/NEMO/templates/area_access/self_login.html +0 -0
  314. {nemo_ce-7.3.6 → nemo_ce-7.3.7}/NEMO/templates/authorization_failed.html +0 -0
  315. {nemo_ce-7.3.6 → nemo_ce-7.3.7}/NEMO/templates/base/footer.html +0 -0
  316. {nemo_ce-7.3.6 → nemo_ce-7.3.7}/NEMO/templates/base/impersonate_header.html +0 -0
  317. {nemo_ce-7.3.6 → nemo_ce-7.3.7}/NEMO/templates/base/navbar.html +0 -0
  318. {nemo_ce-7.3.6 → nemo_ce-7.3.7}/NEMO/templates/base/navbar_base.html +0 -0
  319. {nemo_ce-7.3.6 → nemo_ce-7.3.7}/NEMO/templates/base/popup.html +0 -0
  320. {nemo_ce-7.3.6 → nemo_ce-7.3.7}/NEMO/templates/base.html +0 -0
  321. {nemo_ce-7.3.6 → nemo_ce-7.3.7}/NEMO/templates/calendar/accessories.html +0 -0
  322. {nemo_ce-7.3.6 → nemo_ce-7.3.7}/NEMO/templates/calendar/accessories_helper.html +0 -0
  323. {nemo_ce-7.3.6 → nemo_ce-7.3.7}/NEMO/templates/calendar/calendar.html +0 -0
  324. {nemo_ce-7.3.6 → nemo_ce-7.3.7}/NEMO/templates/calendar/configuration.html +0 -0
  325. {nemo_ce-7.3.6 → nemo_ce-7.3.7}/NEMO/templates/calendar/configuration_event_feed.html +0 -0
  326. {nemo_ce-7.3.6 → nemo_ce-7.3.7}/NEMO/templates/calendar/new_training_event.html +0 -0
  327. {nemo_ce-7.3.6 → nemo_ce-7.3.7}/NEMO/templates/calendar/policy_dialog.html +0 -0
  328. {nemo_ce-7.3.6 → nemo_ce-7.3.7}/NEMO/templates/calendar/project_choice.html +0 -0
  329. {nemo_ce-7.3.6 → nemo_ce-7.3.7}/NEMO/templates/calendar/proxy_reservation.html +0 -0
  330. {nemo_ce-7.3.6 → nemo_ce-7.3.7}/NEMO/templates/calendar/reservation_event_feed.html +0 -0
  331. {nemo_ce-7.3.6 → nemo_ce-7.3.7}/NEMO/templates/calendar/reservation_questions.html +0 -0
  332. {nemo_ce-7.3.6 → nemo_ce-7.3.7}/NEMO/templates/calendar/reservation_warning.html +0 -0
  333. {nemo_ce-7.3.6 → nemo_ce-7.3.7}/NEMO/templates/calendar/scheduled_outage_information.html +0 -0
  334. {nemo_ce-7.3.6 → nemo_ce-7.3.7}/NEMO/templates/calendar/specific_user_feed.html +0 -0
  335. {nemo_ce-7.3.6 → nemo_ce-7.3.7}/NEMO/templates/calendar/usage_event_feed.html +0 -0
  336. {nemo_ce-7.3.6 → nemo_ce-7.3.7}/NEMO/templates/calendar/user_tool_lists.html +0 -0
  337. {nemo_ce-7.3.6 → nemo_ce-7.3.7}/NEMO/templates/configuration/configuration_history.html +0 -0
  338. {nemo_ce-7.3.6 → nemo_ce-7.3.7}/NEMO/templates/configuration/configuration_line_item.html +0 -0
  339. {nemo_ce-7.3.6 → nemo_ce-7.3.7}/NEMO/templates/configuration/configuration_reservation_helper.html +0 -0
  340. {nemo_ce-7.3.6 → nemo_ce-7.3.7}/NEMO/templates/configuration_agenda.html +0 -0
  341. {nemo_ce-7.3.6 → nemo_ce-7.3.7}/NEMO/templates/consumables/consumables.html +0 -0
  342. {nemo_ce-7.3.6 → nemo_ce-7.3.7}/NEMO/templates/consumables/consumables_order.html +0 -0
  343. {nemo_ce-7.3.6 → nemo_ce-7.3.7}/NEMO/templates/consumables/recurring_charge.html +0 -0
  344. {nemo_ce-7.3.6 → nemo_ce-7.3.7}/NEMO/templates/consumables/recurring_charges.html +0 -0
  345. {nemo_ce-7.3.6 → nemo_ce-7.3.7}/NEMO/templates/contact/contact_staff.html +0 -0
  346. {nemo_ce-7.3.6 → nemo_ce-7.3.7}/NEMO/templates/customizations/customizations.html +0 -0
  347. {nemo_ce-7.3.6 → nemo_ce-7.3.7}/NEMO/templates/customizations/customizations_adjustment_requests.html +0 -0
  348. {nemo_ce-7.3.6 → nemo_ce-7.3.7}/NEMO/templates/customizations/customizations_application.html +0 -0
  349. {nemo_ce-7.3.6 → nemo_ce-7.3.7}/NEMO/templates/customizations/customizations_calendar.html +0 -0
  350. {nemo_ce-7.3.6 → nemo_ce-7.3.7}/NEMO/templates/customizations/customizations_dashboard.html +0 -0
  351. {nemo_ce-7.3.6 → nemo_ce-7.3.7}/NEMO/templates/customizations/customizations_emails.html +0 -0
  352. {nemo_ce-7.3.6 → nemo_ce-7.3.7}/NEMO/templates/customizations/customizations_interlock.html +0 -0
  353. {nemo_ce-7.3.6 → nemo_ce-7.3.7}/NEMO/templates/customizations/customizations_knowledge_base.html +0 -0
  354. {nemo_ce-7.3.6 → nemo_ce-7.3.7}/NEMO/templates/customizations/customizations_projects_and_accounts.html +0 -0
  355. {nemo_ce-7.3.6 → nemo_ce-7.3.7}/NEMO/templates/customizations/customizations_rates.html +0 -0
  356. {nemo_ce-7.3.6 → nemo_ce-7.3.7}/NEMO/templates/customizations/customizations_recurring_charges.html +0 -0
  357. {nemo_ce-7.3.6 → nemo_ce-7.3.7}/NEMO/templates/customizations/customizations_remote_work.html +0 -0
  358. {nemo_ce-7.3.6 → nemo_ce-7.3.7}/NEMO/templates/customizations/customizations_requests.html +0 -0
  359. {nemo_ce-7.3.6 → nemo_ce-7.3.7}/NEMO/templates/customizations/customizations_safety.html +0 -0
  360. {nemo_ce-7.3.6 → nemo_ce-7.3.7}/NEMO/templates/customizations/customizations_shadowing_verification.html +0 -0
  361. {nemo_ce-7.3.6 → nemo_ce-7.3.7}/NEMO/templates/customizations/customizations_templates.html +0 -0
  362. {nemo_ce-7.3.6 → nemo_ce-7.3.7}/NEMO/templates/customizations/customizations_training.html +0 -0
  363. {nemo_ce-7.3.6 → nemo_ce-7.3.7}/NEMO/templates/customizations/customizations_upload.html +0 -0
  364. {nemo_ce-7.3.6 → nemo_ce-7.3.7}/NEMO/templates/customizations/customizations_user.html +0 -0
  365. {nemo_ce-7.3.6 → nemo_ce-7.3.7}/NEMO/templates/display_success_and_redirect.html +0 -0
  366. {nemo_ce-7.3.6 → nemo_ce-7.3.7}/NEMO/templates/email/compose_email.html +0 -0
  367. {nemo_ce-7.3.6 → nemo_ce-7.3.7}/NEMO/templates/email/email_broadcast.html +0 -0
  368. {nemo_ce-7.3.6 → nemo_ce-7.3.7}/NEMO/templates/email/email_form.html +0 -0
  369. {nemo_ce-7.3.6 → nemo_ce-7.3.7}/NEMO/templates/event_details/area_access_details.html +0 -0
  370. {nemo_ce-7.3.6 → nemo_ce-7.3.7}/NEMO/templates/event_details/outage_details.html +0 -0
  371. {nemo_ce-7.3.6 → nemo_ce-7.3.7}/NEMO/templates/event_details/reservation_details.html +0 -0
  372. {nemo_ce-7.3.6 → nemo_ce-7.3.7}/NEMO/templates/event_details/training_event_details.html +0 -0
  373. {nemo_ce-7.3.6 → nemo_ce-7.3.7}/NEMO/templates/event_details/usage_details.html +0 -0
  374. {nemo_ce-7.3.6 → nemo_ce-7.3.7}/NEMO/templates/facility_rules.html +0 -0
  375. {nemo_ce-7.3.6 → nemo_ce-7.3.7}/NEMO/templates/feedback.html +0 -0
  376. {nemo_ce-7.3.6 → nemo_ce-7.3.7}/NEMO/templates/history.html +0 -0
  377. {nemo_ce-7.3.6 → nemo_ce-7.3.7}/NEMO/templates/impersonate.html +0 -0
  378. {nemo_ce-7.3.6 → nemo_ce-7.3.7}/NEMO/templates/jumbotron/jumbotron.html +0 -0
  379. {nemo_ce-7.3.6 → nemo_ce-7.3.7}/NEMO/templates/jumbotron/jumbotron_content.html +0 -0
  380. {nemo_ce-7.3.6 → nemo_ce-7.3.7}/NEMO/templates/knowledge_base/knowledge_base.html +0 -0
  381. {nemo_ce-7.3.6 → nemo_ce-7.3.7}/NEMO/templates/knowledge_base/knowledge_base_base.html +0 -0
  382. {nemo_ce-7.3.6 → nemo_ce-7.3.7}/NEMO/templates/knowledge_base/knowledge_base_items.html +0 -0
  383. {nemo_ce-7.3.6 → nemo_ce-7.3.7}/NEMO/templates/landing.html +0 -0
  384. {nemo_ce-7.3.6 → nemo_ce-7.3.7}/NEMO/templates/login.html +0 -0
  385. {nemo_ce-7.3.6 → nemo_ce-7.3.7}/NEMO/templates/maintenance/closed_task_details.html +0 -0
  386. {nemo_ce-7.3.6 → nemo_ce-7.3.7}/NEMO/templates/maintenance/maintenance.html +0 -0
  387. {nemo_ce-7.3.6 → nemo_ce-7.3.7}/NEMO/templates/maintenance/pending_task_details.html +0 -0
  388. {nemo_ce-7.3.6 → nemo_ce-7.3.7}/NEMO/templates/mobile/cancellation_result.html +0 -0
  389. {nemo_ce-7.3.6 → nemo_ce-7.3.7}/NEMO/templates/mobile/choose_item.html +0 -0
  390. {nemo_ce-7.3.6 → nemo_ce-7.3.7}/NEMO/templates/mobile/error.html +0 -0
  391. {nemo_ce-7.3.6 → nemo_ce-7.3.7}/NEMO/templates/mobile/individual_outage.html +0 -0
  392. {nemo_ce-7.3.6 → nemo_ce-7.3.7}/NEMO/templates/mobile/individual_reservation.html +0 -0
  393. {nemo_ce-7.3.6 → nemo_ce-7.3.7}/NEMO/templates/mobile/individual_training_event.html +0 -0
  394. {nemo_ce-7.3.6 → nemo_ce-7.3.7}/NEMO/templates/mobile/new_reservation.html +0 -0
  395. {nemo_ce-7.3.6 → nemo_ce-7.3.7}/NEMO/templates/mobile/no_active_projects.html +0 -0
  396. {nemo_ce-7.3.6 → nemo_ce-7.3.7}/NEMO/templates/mobile/reservation_extra.html +0 -0
  397. {nemo_ce-7.3.6 → nemo_ce-7.3.7}/NEMO/templates/mobile/reservation_success.html +0 -0
  398. {nemo_ce-7.3.6 → nemo_ce-7.3.7}/NEMO/templates/mobile/view_calendar.html +0 -0
  399. {nemo_ce-7.3.6 → nemo_ce-7.3.7}/NEMO/templates/news/archived_news.html +0 -0
  400. {nemo_ce-7.3.6 → nemo_ce-7.3.7}/NEMO/templates/news/new_news_form.html +0 -0
  401. {nemo_ce-7.3.6 → nemo_ce-7.3.7}/NEMO/templates/news/news_update_form.html +0 -0
  402. {nemo_ce-7.3.6 → nemo_ce-7.3.7}/NEMO/templates/news/recent_news.html +0 -0
  403. {nemo_ce-7.3.6 → nemo_ce-7.3.7}/NEMO/templates/occupancy/occupancy.html +0 -0
  404. {nemo_ce-7.3.6 → nemo_ce-7.3.7}/NEMO/templates/occupancy/occupancy_content.html +0 -0
  405. {nemo_ce-7.3.6 → nemo_ce-7.3.7}/NEMO/templates/occupancy/occupancy_count.html +0 -0
  406. {nemo_ce-7.3.6 → nemo_ce-7.3.7}/NEMO/templates/pagination/pagination_base.html +0 -0
  407. {nemo_ce-7.3.6 → nemo_ce-7.3.7}/NEMO/templates/pagination/pagination_column.html +0 -0
  408. {nemo_ce-7.3.6 → nemo_ce-7.3.7}/NEMO/templates/pagination/pagination_pages.html +0 -0
  409. {nemo_ce-7.3.6 → nemo_ce-7.3.7}/NEMO/templates/pagination/pagination_selector.html +0 -0
  410. {nemo_ce-7.3.6 → nemo_ce-7.3.7}/NEMO/templates/qualifications.html +0 -0
  411. {nemo_ce-7.3.6 → nemo_ce-7.3.7}/NEMO/templates/refresh_sidebar_icons.html +0 -0
  412. {nemo_ce-7.3.6 → nemo_ce-7.3.7}/NEMO/templates/remote_work/remote_work.html +0 -0
  413. {nemo_ce-7.3.6 → nemo_ce-7.3.7}/NEMO/templates/remote_work/remote_work_base.html +0 -0
  414. {nemo_ce-7.3.6 → nemo_ce-7.3.7}/NEMO/templates/requests/access_requests/access_request.html +0 -0
  415. {nemo_ce-7.3.6 → nemo_ce-7.3.7}/NEMO/templates/requests/access_requests/access_requests.html +0 -0
  416. {nemo_ce-7.3.6 → nemo_ce-7.3.7}/NEMO/templates/requests/access_requests/access_requests_table.html +0 -0
  417. {nemo_ce-7.3.6 → nemo_ce-7.3.7}/NEMO/templates/requests/adjustment_requests/adjustment_charge_summary_table.html +0 -0
  418. {nemo_ce-7.3.6 → nemo_ce-7.3.7}/NEMO/templates/requests/adjustment_requests/adjustment_request.html +0 -0
  419. {nemo_ce-7.3.6 → nemo_ce-7.3.7}/NEMO/templates/requests/adjustment_requests/adjustment_requests.html +0 -0
  420. {nemo_ce-7.3.6 → nemo_ce-7.3.7}/NEMO/templates/requests/buddy_requests/buddy_request.html +0 -0
  421. {nemo_ce-7.3.6 → nemo_ce-7.3.7}/NEMO/templates/requests/buddy_requests/buddy_requests.html +0 -0
  422. {nemo_ce-7.3.6 → nemo_ce-7.3.7}/NEMO/templates/requests/staff_assistance_requests/open_staff_assistance_requests.html +0 -0
  423. {nemo_ce-7.3.6 → nemo_ce-7.3.7}/NEMO/templates/requests/staff_assistance_requests/resolved_staff_assistance_requests.html +0 -0
  424. {nemo_ce-7.3.6 → nemo_ce-7.3.7}/NEMO/templates/requests/staff_assistance_requests/staff_assistance_requests.html +0 -0
  425. {nemo_ce-7.3.6 → nemo_ce-7.3.7}/NEMO/templates/requests/user_requests.html +0 -0
  426. {nemo_ce-7.3.6 → nemo_ce-7.3.7}/NEMO/templates/resources/modify_resource.html +0 -0
  427. {nemo_ce-7.3.6 → nemo_ce-7.3.7}/NEMO/templates/resources/resource_details.html +0 -0
  428. {nemo_ce-7.3.6 → nemo_ce-7.3.7}/NEMO/templates/resources/resources.html +0 -0
  429. {nemo_ce-7.3.6 → nemo_ce-7.3.7}/NEMO/templates/resources/scheduled_outage.html +0 -0
  430. {nemo_ce-7.3.6 → nemo_ce-7.3.7}/NEMO/templates/rest_framework/api.html +0 -0
  431. {nemo_ce-7.3.6 → nemo_ce-7.3.7}/NEMO/templates/rest_framework/custom_error.html +0 -0
  432. {nemo_ce-7.3.6 → nemo_ce-7.3.7}/NEMO/templates/safety/safety.html +0 -0
  433. {nemo_ce-7.3.6 → nemo_ce-7.3.7}/NEMO/templates/safety/safety_base.html +0 -0
  434. {nemo_ce-7.3.6 → nemo_ce-7.3.7}/NEMO/templates/safety/safety_data_sheets.html +0 -0
  435. {nemo_ce-7.3.6 → nemo_ce-7.3.7}/NEMO/templates/safety/safety_issues.html +0 -0
  436. {nemo_ce-7.3.6 → nemo_ce-7.3.7}/NEMO/templates/safety/safety_issues_create.html +0 -0
  437. {nemo_ce-7.3.6 → nemo_ce-7.3.7}/NEMO/templates/safety/safety_issues_resolved.html +0 -0
  438. {nemo_ce-7.3.6 → nemo_ce-7.3.7}/NEMO/templates/safety/safety_issues_update.html +0 -0
  439. {nemo_ce-7.3.6 → nemo_ce-7.3.7}/NEMO/templates/safety/safety_items.html +0 -0
  440. {nemo_ce-7.3.6 → nemo_ce-7.3.7}/NEMO/templates/shadowing_verification/shadowing_verification_request.html +0 -0
  441. {nemo_ce-7.3.6 → nemo_ce-7.3.7}/NEMO/templates/shadowing_verification/shadowing_verification_requests.html +0 -0
  442. {nemo_ce-7.3.6 → nemo_ce-7.3.7}/NEMO/templates/shadowing_verification/shadowing_verification_requests_table.html +0 -0
  443. {nemo_ce-7.3.6 → nemo_ce-7.3.7}/NEMO/templates/snippets/admin_json_editor.html +0 -0
  444. {nemo_ce-7.3.6 → nemo_ce-7.3.7}/NEMO/templates/snippets/button.html +0 -0
  445. {nemo_ce-7.3.6 → nemo_ce-7.3.7}/NEMO/templates/snippets/confirm_action_modal.html +0 -0
  446. {nemo_ce-7.3.6 → nemo_ce-7.3.7}/NEMO/templates/snippets/contact_person.html +0 -0
  447. {nemo_ce-7.3.6 → nemo_ce-7.3.7}/NEMO/templates/snippets/document_list.html +0 -0
  448. {nemo_ce-7.3.6 → nemo_ce-7.3.7}/NEMO/templates/snippets/embedded_document.html +0 -0
  449. {nemo_ce-7.3.6 → nemo_ce-7.3.7}/NEMO/templates/snippets/item_status_icons.html +0 -0
  450. {nemo_ce-7.3.6 → nemo_ce-7.3.7}/NEMO/templates/snippets/tool_calendar_info.html +0 -0
  451. {nemo_ce-7.3.6 → nemo_ce-7.3.7}/NEMO/templates/snippets/tool_info.html +0 -0
  452. {nemo_ce-7.3.6 → nemo_ce-7.3.7}/NEMO/templates/snippets/tool_reservation_info.html +0 -0
  453. {nemo_ce-7.3.6 → nemo_ce-7.3.7}/NEMO/templates/staff_charges/change_status.html +0 -0
  454. {nemo_ce-7.3.6 → nemo_ce-7.3.7}/NEMO/templates/staff_charges/choose_project.html +0 -0
  455. {nemo_ce-7.3.6 → nemo_ce-7.3.7}/NEMO/templates/staff_charges/end_area_charge.html +0 -0
  456. {nemo_ce-7.3.6 → nemo_ce-7.3.7}/NEMO/templates/staff_charges/new_staff_charge.html +0 -0
  457. {nemo_ce-7.3.6 → nemo_ce-7.3.7}/NEMO/templates/staff_charges/reminder.html +0 -0
  458. {nemo_ce-7.3.6 → nemo_ce-7.3.7}/NEMO/templates/staff_charges/staff_charges_base.html +0 -0
  459. {nemo_ce-7.3.6 → nemo_ce-7.3.7}/NEMO/templates/status_dashboard/alerts.html +0 -0
  460. {nemo_ce-7.3.6 → nemo_ce-7.3.7}/NEMO/templates/status_dashboard/occupancy.html +0 -0
  461. {nemo_ce-7.3.6 → nemo_ce-7.3.7}/NEMO/templates/status_dashboard/staff.html +0 -0
  462. {nemo_ce-7.3.6 → nemo_ce-7.3.7}/NEMO/templates/status_dashboard/staff_absence.html +0 -0
  463. {nemo_ce-7.3.6 → nemo_ce-7.3.7}/NEMO/templates/status_dashboard/status_dashboard.html +0 -0
  464. {nemo_ce-7.3.6 → nemo_ce-7.3.7}/NEMO/templates/status_dashboard/tools.html +0 -0
  465. {nemo_ce-7.3.6 → nemo_ce-7.3.7}/NEMO/templates/tasks/resolve.html +0 -0
  466. {nemo_ce-7.3.6 → nemo_ce-7.3.7}/NEMO/templates/tasks/update.html +0 -0
  467. {nemo_ce-7.3.6 → nemo_ce-7.3.7}/NEMO/templates/tool_control/get_projects.html +0 -0
  468. {nemo_ce-7.3.6 → nemo_ce-7.3.7}/NEMO/templates/tool_control/interlock_error.html +0 -0
  469. {nemo_ce-7.3.6 → nemo_ce-7.3.7}/NEMO/templates/tool_control/logout_user.html +0 -0
  470. {nemo_ce-7.3.6 → nemo_ce-7.3.7}/NEMO/templates/tool_control/past_tasks_and_comments.html +0 -0
  471. {nemo_ce-7.3.6 → nemo_ce-7.3.7}/NEMO/templates/tool_control/qualified_users.html +0 -0
  472. {nemo_ce-7.3.6 → nemo_ce-7.3.7}/NEMO/templates/tool_control/tool_control.html +0 -0
  473. {nemo_ce-7.3.6 → nemo_ce-7.3.7}/NEMO/templates/tool_control/use_tool_for_other.html +0 -0
  474. {nemo_ce-7.3.6 → nemo_ce-7.3.7}/NEMO/templates/tool_credentials/tool_credentials.html +0 -0
  475. {nemo_ce-7.3.6 → nemo_ce-7.3.7}/NEMO/templates/training/get_projects.html +0 -0
  476. {nemo_ce-7.3.6 → nemo_ce-7.3.7}/NEMO/templates/training/training.html +0 -0
  477. {nemo_ce-7.3.6 → nemo_ce-7.3.7}/NEMO/templates/training/training_entry.html +0 -0
  478. {nemo_ce-7.3.6 → nemo_ce-7.3.7}/NEMO/templates/training/training_recording.html +0 -0
  479. {nemo_ce-7.3.6 → nemo_ce-7.3.7}/NEMO/templates/training_new/training_base.html +0 -0
  480. {nemo_ce-7.3.6 → nemo_ce-7.3.7}/NEMO/templates/training_new/training_events/create_event.html +0 -0
  481. {nemo_ce-7.3.6 → nemo_ce-7.3.7}/NEMO/templates/training_new/training_events/manage_training_events.html +0 -0
  482. {nemo_ce-7.3.6 → nemo_ce-7.3.7}/NEMO/templates/training_new/training_events/manage_training_events_table.html +0 -0
  483. {nemo_ce-7.3.6 → nemo_ce-7.3.7}/NEMO/templates/training_new/training_events/schedule_training_events.html +0 -0
  484. {nemo_ce-7.3.6 → nemo_ce-7.3.7}/NEMO/templates/training_new/training_events/schedule_training_events_list.html +0 -0
  485. {nemo_ce-7.3.6 → nemo_ce-7.3.7}/NEMO/templates/training_new/training_events/upcoming_training_events.html +0 -0
  486. {nemo_ce-7.3.6 → nemo_ce-7.3.7}/NEMO/templates/training_new/training_history.html +0 -0
  487. {nemo_ce-7.3.6 → nemo_ce-7.3.7}/NEMO/templates/training_new/training_requests/create_request.html +0 -0
  488. {nemo_ce-7.3.6 → nemo_ce-7.3.7}/NEMO/templates/training_new/training_requests/training_requests.html +0 -0
  489. {nemo_ce-7.3.6 → nemo_ce-7.3.7}/NEMO/templates/training_new/training_sessions.html +0 -0
  490. {nemo_ce-7.3.6 → nemo_ce-7.3.7}/NEMO/templates/usage/adjustment_request_button.html +0 -0
  491. {nemo_ce-7.3.6 → nemo_ce-7.3.7}/NEMO/templates/usage/billing.html +0 -0
  492. {nemo_ce-7.3.6 → nemo_ce-7.3.7}/NEMO/templates/usage/usage.html +0 -0
  493. {nemo_ce-7.3.6 → nemo_ce-7.3.7}/NEMO/templates/usage/usage_base.html +0 -0
  494. {nemo_ce-7.3.6 → nemo_ce-7.3.7}/NEMO/templates/users/create_or_modify_user.html +0 -0
  495. {nemo_ce-7.3.6 → nemo_ce-7.3.7}/NEMO/templates/users/preferences.html +0 -0
  496. {nemo_ce-7.3.6 → nemo_ce-7.3.7}/NEMO/templates/users/safe_deactivation.html +0 -0
  497. {nemo_ce-7.3.6 → nemo_ce-7.3.7}/NEMO/templates/users/users.html +0 -0
  498. {nemo_ce-7.3.6 → nemo_ce-7.3.7}/NEMO/templates/users/view_user.html +0 -0
  499. {nemo_ce-7.3.6 → nemo_ce-7.3.7}/NEMO/templatetags/__init__.py +0 -0
  500. {nemo_ce-7.3.6 → nemo_ce-7.3.7}/NEMO/templatetags/custom_tags_and_filters.py +0 -0
  501. {nemo_ce-7.3.6 → nemo_ce-7.3.7}/NEMO/templatetags/training_tags.py +0 -0
  502. {nemo_ce-7.3.6 → nemo_ce-7.3.7}/NEMO/tests/__init__.py +0 -0
  503. {nemo_ce-7.3.6 → nemo_ce-7.3.7}/NEMO/tests/test_admin.py +0 -0
  504. {nemo_ce-7.3.6 → nemo_ce-7.3.7}/NEMO/tests/test_api/__init__.py +0 -0
  505. {nemo_ce-7.3.6 → nemo_ce-7.3.7}/NEMO/tests/test_api/test_billing.py +0 -0
  506. {nemo_ce-7.3.6 → nemo_ce-7.3.7}/NEMO/tests/test_api/test_crud.py +0 -0
  507. {nemo_ce-7.3.6 → nemo_ce-7.3.7}/NEMO/tests/test_area_access.py +0 -0
  508. {nemo_ce-7.3.6 → nemo_ce-7.3.7}/NEMO/tests/test_calendar/__init__.py +0 -0
  509. {nemo_ce-7.3.6 → nemo_ce-7.3.7}/NEMO/tests/test_calendar/test_area_reservation.py +0 -0
  510. {nemo_ce-7.3.6 → nemo_ce-7.3.7}/NEMO/tests/test_calendar/test_calendar.py +0 -0
  511. {nemo_ce-7.3.6 → nemo_ce-7.3.7}/NEMO/tests/test_calendar/test_outage.py +0 -0
  512. {nemo_ce-7.3.6 → nemo_ce-7.3.7}/NEMO/tests/test_calendar/test_tool_freed_time.py +0 -0
  513. {nemo_ce-7.3.6 → nemo_ce-7.3.7}/NEMO/tests/test_calendar/test_tool_reservation.py +0 -0
  514. {nemo_ce-7.3.6 → nemo_ce-7.3.7}/NEMO/tests/test_ce/__init__.py +0 -0
  515. {nemo_ce-7.3.6 → nemo_ce-7.3.7}/NEMO/tests/test_ce/test_grant_access_email.py +0 -0
  516. {nemo_ce-7.3.6 → nemo_ce-7.3.7}/NEMO/tests/test_ce/test_precursor_schedule.py +0 -0
  517. {nemo_ce-7.3.6 → nemo_ce-7.3.7}/NEMO/tests/test_ce/test_trainings_auto_cancel.py +0 -0
  518. {nemo_ce-7.3.6 → nemo_ce-7.3.7}/NEMO/tests/test_closures.py +0 -0
  519. {nemo_ce-7.3.6 → nemo_ce-7.3.7}/NEMO/tests/test_consumables.py +0 -0
  520. {nemo_ce-7.3.6 → nemo_ce-7.3.7}/NEMO/tests/test_deactivate_access_expired_users.py +0 -0
  521. {nemo_ce-7.3.6 → nemo_ce-7.3.7}/NEMO/tests/test_dynamic_form.py +0 -0
  522. {nemo_ce-7.3.6 → nemo_ce-7.3.7}/NEMO/tests/test_evaluators.py +0 -0
  523. {nemo_ce-7.3.6 → nemo_ce-7.3.7}/NEMO/tests/test_formats.py +0 -0
  524. {nemo_ce-7.3.6 → nemo_ce-7.3.7}/NEMO/tests/test_interlocks/__init__.py +0 -0
  525. {nemo_ce-7.3.6 → nemo_ce-7.3.7}/NEMO/tests/test_interlocks/test_modbus_interlock.py +0 -0
  526. {nemo_ce-7.3.6 → nemo_ce-7.3.7}/NEMO/tests/test_interlocks/test_stanford_interlock.py +0 -0
  527. {nemo_ce-7.3.6 → nemo_ce-7.3.7}/NEMO/tests/test_interlocks/test_web_relay_interlock.py +0 -0
  528. {nemo_ce-7.3.6 → nemo_ce-7.3.7}/NEMO/tests/test_misc.py +0 -0
  529. {nemo_ce-7.3.6 → nemo_ce-7.3.7}/NEMO/tests/test_requests/__init__.py +0 -0
  530. {nemo_ce-7.3.6 → nemo_ce-7.3.7}/NEMO/tests/test_requests/test_adjustment_requests.py +0 -0
  531. {nemo_ce-7.3.6 → nemo_ce-7.3.7}/NEMO/tests/test_send_email.py +0 -0
  532. {nemo_ce-7.3.6 → nemo_ce-7.3.7}/NEMO/tests/test_settings.py +0 -0
  533. {nemo_ce-7.3.6 → nemo_ce-7.3.7}/NEMO/tests/test_shadowing_verification.py +0 -0
  534. {nemo_ce-7.3.6 → nemo_ce-7.3.7}/NEMO/tests/test_staff_charges.py +0 -0
  535. {nemo_ce-7.3.6 → nemo_ce-7.3.7}/NEMO/tests/test_staff_on_tool.py +0 -0
  536. {nemo_ce-7.3.6 → nemo_ce-7.3.7}/NEMO/tests/test_tools/__init__.py +0 -0
  537. {nemo_ce-7.3.6 → nemo_ce-7.3.7}/NEMO/tests/test_tools/test_tool.py +0 -0
  538. {nemo_ce-7.3.6 → nemo_ce-7.3.7}/NEMO/tests/test_tools/test_waitlist.py +0 -0
  539. {nemo_ce-7.3.6 → nemo_ce-7.3.7}/NEMO/tests/test_urls.py +0 -0
  540. {nemo_ce-7.3.6 → nemo_ce-7.3.7}/NEMO/tests/test_urls_api.py +0 -0
  541. {nemo_ce-7.3.6 → nemo_ce-7.3.7}/NEMO/tests/test_users.py +0 -0
  542. {nemo_ce-7.3.6 → nemo_ce-7.3.7}/NEMO/tests/test_utilities.py +0 -0
  543. {nemo_ce-7.3.6 → nemo_ce-7.3.7}/NEMO/typing.py +0 -0
  544. {nemo_ce-7.3.6 → nemo_ce-7.3.7}/NEMO/urls.py +0 -0
  545. {nemo_ce-7.3.6 → nemo_ce-7.3.7}/NEMO/utilities.py +0 -0
  546. {nemo_ce-7.3.6 → nemo_ce-7.3.7}/NEMO/validators.py +0 -0
  547. {nemo_ce-7.3.6 → nemo_ce-7.3.7}/NEMO/views/__init__.py +0 -0
  548. {nemo_ce-7.3.6 → nemo_ce-7.3.7}/NEMO/views/abuse.py +0 -0
  549. {nemo_ce-7.3.6 → nemo_ce-7.3.7}/NEMO/views/access_requests.py +0 -0
  550. {nemo_ce-7.3.6 → nemo_ce-7.3.7}/NEMO/views/accounts_and_projects.py +0 -0
  551. {nemo_ce-7.3.6 → nemo_ce-7.3.7}/NEMO/views/adjustment_requests.py +0 -0
  552. {nemo_ce-7.3.6 → nemo_ce-7.3.7}/NEMO/views/admin_autocomplete.py +0 -0
  553. {nemo_ce-7.3.6 → nemo_ce-7.3.7}/NEMO/views/alerts.py +0 -0
  554. {nemo_ce-7.3.6 → nemo_ce-7.3.7}/NEMO/views/api_billing.py +0 -0
  555. {nemo_ce-7.3.6 → nemo_ce-7.3.7}/NEMO/views/area_access.py +0 -0
  556. {nemo_ce-7.3.6 → nemo_ce-7.3.7}/NEMO/views/authentication.py +0 -0
  557. {nemo_ce-7.3.6 → nemo_ce-7.3.7}/NEMO/views/buddy_requests.py +0 -0
  558. {nemo_ce-7.3.6 → nemo_ce-7.3.7}/NEMO/views/charge_validation.py +0 -0
  559. {nemo_ce-7.3.6 → nemo_ce-7.3.7}/NEMO/views/configuration_agenda.py +0 -0
  560. {nemo_ce-7.3.6 → nemo_ce-7.3.7}/NEMO/views/constants.py +0 -0
  561. {nemo_ce-7.3.6 → nemo_ce-7.3.7}/NEMO/views/consumables.py +0 -0
  562. {nemo_ce-7.3.6 → nemo_ce-7.3.7}/NEMO/views/contact_staff.py +0 -0
  563. {nemo_ce-7.3.6 → nemo_ce-7.3.7}/NEMO/views/documents.py +0 -0
  564. {nemo_ce-7.3.6 → nemo_ce-7.3.7}/NEMO/views/email.py +0 -0
  565. {nemo_ce-7.3.6 → nemo_ce-7.3.7}/NEMO/views/event_details.py +0 -0
  566. {nemo_ce-7.3.6 → nemo_ce-7.3.7}/NEMO/views/feedback.py +0 -0
  567. {nemo_ce-7.3.6 → nemo_ce-7.3.7}/NEMO/views/get_projects.py +0 -0
  568. {nemo_ce-7.3.6 → nemo_ce-7.3.7}/NEMO/views/history.py +0 -0
  569. {nemo_ce-7.3.6 → nemo_ce-7.3.7}/NEMO/views/jumbotron.py +0 -0
  570. {nemo_ce-7.3.6 → nemo_ce-7.3.7}/NEMO/views/knowledge_base.py +0 -0
  571. {nemo_ce-7.3.6 → nemo_ce-7.3.7}/NEMO/views/landing.py +0 -0
  572. {nemo_ce-7.3.6 → nemo_ce-7.3.7}/NEMO/views/maintenance.py +0 -0
  573. {nemo_ce-7.3.6 → nemo_ce-7.3.7}/NEMO/views/mobile.py +0 -0
  574. {nemo_ce-7.3.6 → nemo_ce-7.3.7}/NEMO/views/news.py +0 -0
  575. {nemo_ce-7.3.6 → nemo_ce-7.3.7}/NEMO/views/notifications.py +0 -0
  576. {nemo_ce-7.3.6 → nemo_ce-7.3.7}/NEMO/views/pagination.py +0 -0
  577. {nemo_ce-7.3.6 → nemo_ce-7.3.7}/NEMO/views/qualifications.py +0 -0
  578. {nemo_ce-7.3.6 → nemo_ce-7.3.7}/NEMO/views/remote_work.py +0 -0
  579. {nemo_ce-7.3.6 → nemo_ce-7.3.7}/NEMO/views/resources.py +0 -0
  580. {nemo_ce-7.3.6 → nemo_ce-7.3.7}/NEMO/views/safety.py +0 -0
  581. {nemo_ce-7.3.6 → nemo_ce-7.3.7}/NEMO/views/shadowing_verification.py +0 -0
  582. {nemo_ce-7.3.6 → nemo_ce-7.3.7}/NEMO/views/sidebar.py +0 -0
  583. {nemo_ce-7.3.6 → nemo_ce-7.3.7}/NEMO/views/staff_assistance_requests.py +0 -0
  584. {nemo_ce-7.3.6 → nemo_ce-7.3.7}/NEMO/views/status_dashboard.py +0 -0
  585. {nemo_ce-7.3.6 → nemo_ce-7.3.7}/NEMO/views/tasks.py +0 -0
  586. {nemo_ce-7.3.6 → nemo_ce-7.3.7}/NEMO/views/tool_credentials.py +0 -0
  587. {nemo_ce-7.3.6 → nemo_ce-7.3.7}/NEMO/views/training.py +0 -0
  588. {nemo_ce-7.3.6 → nemo_ce-7.3.7}/NEMO/views/training_new.py +0 -0
  589. {nemo_ce-7.3.6 → nemo_ce-7.3.7}/NEMO/views/tutorials.py +0 -0
  590. {nemo_ce-7.3.6 → nemo_ce-7.3.7}/NEMO/views/usage.py +0 -0
  591. {nemo_ce-7.3.6 → nemo_ce-7.3.7}/NEMO/views/user_requests.py +0 -0
  592. {nemo_ce-7.3.6 → nemo_ce-7.3.7}/NEMO/views/users.py +0 -0
  593. {nemo_ce-7.3.6 → nemo_ce-7.3.7}/NEMO/widgets/__init__.py +0 -0
  594. {nemo_ce-7.3.6 → nemo_ce-7.3.7}/NEMO/widgets/configuration_editor.py +0 -0
  595. {nemo_ce-7.3.6 → nemo_ce-7.3.7}/NEMO/widgets/dynamic_form.py +0 -0
  596. {nemo_ce-7.3.6 → nemo_ce-7.3.7}/NEMO/widgets/item_tree.py +0 -0
  597. {nemo_ce-7.3.6 → nemo_ce-7.3.7}/NEMO/wsgi.py +0 -0
  598. {nemo_ce-7.3.6 → nemo_ce-7.3.7}/NEMO_CE.egg-info/dependency_links.txt +0 -0
  599. {nemo_ce-7.3.6 → nemo_ce-7.3.7}/NEMO_CE.egg-info/entry_points.txt +0 -0
  600. {nemo_ce-7.3.6 → nemo_ce-7.3.7}/NEMO_CE.egg-info/requires.txt +0 -0
  601. {nemo_ce-7.3.6 → nemo_ce-7.3.7}/NEMO_CE.egg-info/top_level.txt +0 -0
  602. {nemo_ce-7.3.6 → nemo_ce-7.3.7}/README.md +0 -0
  603. {nemo_ce-7.3.6 → nemo_ce-7.3.7}/setup.cfg +0 -0
@@ -287,7 +287,7 @@ class ToolAdmin(admin.ModelAdmin):
287
287
  "parent_tool",
288
288
  "_category",
289
289
  "_operation_mode",
290
- "_qualifications_never_expire",
290
+ "qualified_users",
291
291
  "_problem_shutdown_enabled",
292
292
  "_reservation_required",
293
293
  "_logout_grace_period",
@@ -342,6 +342,17 @@ class ToolAdmin(admin.ModelAdmin):
342
342
  )
343
343
  },
344
344
  ),
345
+ (
346
+ "Qualification expiration",
347
+ {
348
+ "fields": (
349
+ "_qualification_reminder_days",
350
+ "_qualification_expiration_days",
351
+ "_qualification_expiration_never_used_days",
352
+ "_qualification_notification_email",
353
+ )
354
+ },
355
+ ),
345
356
  (
346
357
  "Area Access",
347
358
  {
@@ -0,0 +1,103 @@
1
+ # Generated by Django 4.2.27 on 2026-01-26 20:42
2
+
3
+ import re
4
+
5
+ import django.core.validators
6
+ import django.db.models.deletion
7
+ from django.db import migrations, models
8
+
9
+ import NEMO.fields
10
+
11
+
12
+ def migrate_tool_qualification_expiration_forward(apps, schema_editor):
13
+ Tool = apps.get_model("NEMO", "Tool")
14
+ Customization = apps.get_model("NEMO", "Customization")
15
+ tool_qualification_reminder_days = Customization.objects.filter(name="tool_qualification_reminder_days").first()
16
+ tool_qualification_expiration_days = Customization.objects.filter(name="tool_qualification_expiration_days").first()
17
+ tool_qualification_expiration_never_used_days = Customization.objects.filter(
18
+ name="tool_qualification_expiration_never_used_days"
19
+ ).first()
20
+ tool_qualification_notification = Customization.objects.filter(name="tool_qualification_cc").first()
21
+ for tool in Tool.objects.filter(_qualifications_never_expire=False, parent_tool__isnull=True):
22
+ if tool_qualification_expiration_days or tool_qualification_expiration_never_used_days:
23
+ if tool_qualification_reminder_days and tool_qualification_reminder_days.value:
24
+ tool._qualification_reminder_days = tool_qualification_reminder_days.value
25
+ if tool_qualification_expiration_days and tool_qualification_expiration_days.value:
26
+ tool._qualification_expiration_days = tool_qualification_expiration_days.value
27
+ if tool_qualification_expiration_never_used_days and tool_qualification_expiration_never_used_days.value:
28
+ tool._qualification_expiration_never_used_days = tool_qualification_expiration_never_used_days.value
29
+ if tool_qualification_notification and tool_qualification_notification.value:
30
+ tool._qualification_notification_email = tool_qualification_notification.value
31
+ tool.save()
32
+ if tool_qualification_reminder_days:
33
+ tool_qualification_reminder_days.delete()
34
+ if tool_qualification_expiration_days:
35
+ tool_qualification_expiration_days.delete()
36
+ if tool_qualification_expiration_never_used_days:
37
+ tool_qualification_expiration_never_used_days.delete()
38
+ if tool_qualification_notification:
39
+ tool_qualification_notification.delete()
40
+
41
+
42
+ class Migration(migrations.Migration):
43
+
44
+ dependencies = [
45
+ ("NEMO", "0140_alter_user_options"),
46
+ ]
47
+
48
+ operations = [
49
+ migrations.AddField(
50
+ model_name="tool",
51
+ name="_qualification_expiration_days",
52
+ field=models.PositiveIntegerField(
53
+ db_column="qualification_expiration_days",
54
+ blank=True,
55
+ help_text="The number of days from the user’s last tool use until the qualification expires.",
56
+ null=True,
57
+ ),
58
+ ),
59
+ migrations.AddField(
60
+ model_name="tool",
61
+ name="_qualification_expiration_never_used_days",
62
+ field=models.PositiveIntegerField(
63
+ db_column="qualification_expiration_never_used_days",
64
+ blank=True,
65
+ help_text="Number of days from the user's first qualification until the qualification expires (if the user never used the tool).",
66
+ null=True,
67
+ ),
68
+ ),
69
+ migrations.AddField(
70
+ model_name="tool",
71
+ name="_qualification_notification_email",
72
+ field=NEMO.fields.MultiEmailField(
73
+ db_column="qualification_notification_email",
74
+ blank=True,
75
+ help_text="The email addresses to cc on tool qualification expiration and on reminders. Separate multiple emails with commas.",
76
+ max_length=2000,
77
+ null=True,
78
+ ),
79
+ ),
80
+ migrations.AddField(
81
+ model_name="tool",
82
+ name="_qualification_reminder_days",
83
+ field=models.CharField(
84
+ db_column="qualification_reminder_days",
85
+ blank=True,
86
+ help_text="The (optional) number of days to send a reminder prior to the user's tool qualification expiration (below). A comma-separated list can be used for multiple reminders. This applies to both expiration cases.",
87
+ max_length=255,
88
+ null=True,
89
+ validators=[
90
+ django.core.validators.RegexValidator(
91
+ re.compile("^\\d+(?:,\\d+)*\\Z"),
92
+ code="invalid",
93
+ message="Enter only digits separated by commas.",
94
+ )
95
+ ],
96
+ ),
97
+ ),
98
+ migrations.RunPython(migrate_tool_qualification_expiration_forward, migrations.RunPython.noop),
99
+ migrations.RemoveField(
100
+ model_name="tool",
101
+ name="_qualifications_never_expire",
102
+ ),
103
+ ]
@@ -1349,10 +1349,32 @@ class Tool(SerializationByNameModel):
1349
1349
  _interlock = models.OneToOneField(
1350
1350
  "Interlock", db_column="interlock_id", blank=True, null=True, on_delete=models.SET_NULL
1351
1351
  )
1352
- _qualifications_never_expire = models.BooleanField(
1353
- default=False,
1354
- db_column="qualifications_never_expire",
1355
- help_text="Check this box if qualifications for this tool should never expire (even if the tool qualification expiration feature is enabled).",
1352
+ # Qualification expiration fields
1353
+ _qualification_reminder_days = models.CharField(
1354
+ db_column="qualification_reminder_days",
1355
+ null=True,
1356
+ blank=True,
1357
+ max_length=CHAR_FIELD_MEDIUM_LENGTH,
1358
+ validators=[validate_comma_separated_integer_list],
1359
+ help_text="The (optional) number of days to send a reminder prior to the user's tool qualification expiration (below). A comma-separated list can be used for multiple reminders. This applies to both expiration cases.",
1360
+ )
1361
+ _qualification_expiration_days = models.PositiveIntegerField(
1362
+ db_column="qualification_expiration_days",
1363
+ null=True,
1364
+ blank=True,
1365
+ help_text="The number of days from the user’s last tool use until the qualification expires.",
1366
+ )
1367
+ _qualification_expiration_never_used_days = models.PositiveIntegerField(
1368
+ db_column="qualification_expiration_never_used_days",
1369
+ null=True,
1370
+ blank=True,
1371
+ help_text="Number of days from the user's first qualification until the qualification expires (if the user never used the tool).",
1372
+ )
1373
+ _qualification_notification_email = fields.MultiEmailField(
1374
+ db_column="qualification_notification_email",
1375
+ null=True,
1376
+ blank=True,
1377
+ help_text="The email addresses to cc on tool qualification expiration and on reminders. Separate multiple emails with commas.",
1356
1378
  )
1357
1379
  # Policy fields:
1358
1380
  _requires_area_access = TreeForeignKey(
@@ -1530,17 +1552,6 @@ class Tool(SerializationByNameModel):
1530
1552
  self.raise_setter_error_if_child_tool("category")
1531
1553
  self._category = value
1532
1554
 
1533
- @property
1534
- def qualifications_never_expire(self):
1535
- return (
1536
- self.parent_tool.qualifications_never_expire if self.is_child_tool() else self._qualifications_never_expire
1537
- )
1538
-
1539
- @qualifications_never_expire.setter
1540
- def qualifications_never_expire(self, value):
1541
- self.raise_setter_error_if_child_tool("qualifications_never_expire")
1542
- self._qualifications_never_expire = value
1543
-
1544
1555
  @property
1545
1556
  def description(self):
1546
1557
  return self.parent_tool.description if self.is_child_tool() else self._description
@@ -1689,6 +1700,56 @@ class Tool(SerializationByNameModel):
1689
1700
  self.raise_setter_error_if_child_tool("interlock")
1690
1701
  self._interlock = value
1691
1702
 
1703
+ @property
1704
+ def qualification_reminder_days(self):
1705
+ return (
1706
+ self.parent_tool.qualification_reminder_days if self.is_child_tool() else self._qualification_reminder_days
1707
+ )
1708
+
1709
+ @qualification_reminder_days.setter
1710
+ def qualification_reminder_days(self, value):
1711
+ self.raise_setter_error_if_child_tool("qualification_reminder_days")
1712
+ self._qualification_reminder_days = value
1713
+
1714
+ @property
1715
+ def qualification_expiration_days(self):
1716
+ return (
1717
+ self.parent_tool.qualification_expiration_days
1718
+ if self.is_child_tool()
1719
+ else self._qualification_expiration_days
1720
+ )
1721
+
1722
+ @qualification_expiration_days.setter
1723
+ def qualification_expiration_days(self, value):
1724
+ self.raise_setter_error_if_child_tool("qualification_expiration_days")
1725
+ self._qualification_expiration_days = value
1726
+
1727
+ @property
1728
+ def qualification_expiration_never_used_days(self):
1729
+ return (
1730
+ self.parent_tool.qualification_expiration_never_used_days
1731
+ if self.is_child_tool()
1732
+ else self._qualification_expiration_never_used_days
1733
+ )
1734
+
1735
+ @qualification_expiration_never_used_days.setter
1736
+ def qualification_expiration_never_used_days(self, value):
1737
+ self.raise_setter_error_if_child_tool("qualification_expiration_never_used_days")
1738
+ self._qualification_expiration_never_used_days = value
1739
+
1740
+ @property
1741
+ def qualification_notification_email(self):
1742
+ return (
1743
+ self.parent_tool.qualification_notification_email
1744
+ if self.is_child_tool()
1745
+ else self._qualification_notification_email
1746
+ )
1747
+
1748
+ @qualification_notification_email.setter
1749
+ def qualification_notification_email(self, value):
1750
+ self.raise_setter_error_if_child_tool("qualification_notification_email")
1751
+ self._qualification_notification_email = value
1752
+
1692
1753
  @property
1693
1754
  def requires_area_access(self):
1694
1755
  return self.parent_tool.requires_area_access if self.is_child_tool() else self._requires_area_access
@@ -2379,6 +2440,11 @@ class Tool(SerializationByNameModel):
2379
2440
  else:
2380
2441
  raise ValueError(f"A {'project' if user else 'user'} must be provided for usage questions")
2381
2442
 
2443
+ def get_qualification_reminder_days(self) -> List[int]:
2444
+ if not self.qualification_reminder_days:
2445
+ return []
2446
+ return [int(days) for days in self.qualification_reminder_days.split(",") if days]
2447
+
2382
2448
  def clean(self):
2383
2449
  errors = {}
2384
2450
  if self.parent_tool_id:
@@ -623,97 +623,14 @@
623
623
  </div>
624
624
  </div>
625
625
  <div class="customization-separation" style="margin-bottom: 15px"></div>
626
- <h3 class="customization-section-title">Tool qualification expiration</h3>
627
- <p>
628
- If active, this feature will remove tool qualification from a user if the user has not used the tool after a while or never used it since qualified (configured separately).
629
- <p>
630
- The <a href="{% url 'customization' 'templates' %}?#tool_qualification_expiration_email_id">user tool qualification expiration email</a> need to be set to enable this feature.
631
- </p>
632
- <br />
633
- <div class="form-group {% if errors.tool_qualification_reminder_days %}has-error{% endif %}">
634
- <label class="control-label col-md-3" for="tool_qualification_reminder_days">Reminder days</label>
635
- <div class="col-md-5">
636
- <input type="text"
637
- id="tool_qualification_reminder_days"
638
- name="tool_qualification_reminder_days"
639
- class="form-control"
640
- value="{% if errors.tool_qualification_reminder_days %}{{ errors.tool_qualification_reminder_days.value }}{% else %}{{ tool_qualification_reminder_days }}{% endif %}" />
641
- </div>
642
- <div class="col-md-offset-3 col-md-9 help-block light-grey">
643
- {% if errors.tool_qualification_reminder_days %}
644
- {{ errors.tool_qualification_reminder_days.error }}
645
- {% else %}
646
- The (optional) number of days to send a reminder prior to the user's tool qualification expiration (below). A comma-separated list can be used for multiple reminders. This applies to both expiration cases.
647
- {% endif %}
648
- </div>
649
- </div>
650
- <div class="form-group {% if errors.tool_qualification_expiration_days %}has-error{% endif %}">
651
- <label class="control-label col-md-3" for="tool_qualification_expiration_days">
652
- Expiration days (previous tool usage)
653
- </label>
654
- <div class="col-md-5">
655
- <input type="number"
656
- step="1"
657
- id="tool_qualification_expiration_days"
658
- name="tool_qualification_expiration_days"
659
- class="form-control"
660
- value="{% if errors.tool_qualification_expiration_days %}{{ errors.tool_qualification_expiration_days.value }}{% else %}{{ tool_qualification_expiration_days }}{% endif %}" />
661
- </div>
662
- <div class="col-md-offset-3 col-md-9 help-block light-grey">
663
- {% if errors.tool_qualification_expiration_days %}
664
- {{ errors.tool_qualification_expiration_days.error }}
665
- {% else %}
666
- The number of days before the user's tool qualification expires since the user last used the tool.
667
- {% endif %}
668
- </div>
669
- </div>
670
- <div class="form-group {% if errors.tool_qualification_expiration_never_used_days %}has-error{% endif %}">
671
- <label class="control-label col-md-3" for="tool_qualification_expiration_never_used_days">
672
- Expiration days (no tool usage)
673
- </label>
674
- <div class="col-md-5">
675
- <input type="number"
676
- step="1"
677
- id="tool_qualification_expiration_never_used_days"
678
- name="tool_qualification_expiration_never_used_days"
679
- class="form-control"
680
- value="{% if errors.tool_qualification_expiration_never_used_days %}{{ errors.tool_qualification_expiration_never_used_days.value }}{% else %}{{ tool_qualification_expiration_never_used_days }}{% endif %}" />
681
- </div>
682
- <div class="col-md-offset-3 col-md-9 help-block light-grey">
683
- {% if errors.tool_qualification_expiration_never_used_days %}
684
- {{ errors.tool_qualification_expiration_never_used_days.error }}
685
- {% else %}
686
- The number of days before the user's tool qualification expires since the user qualified for the first time.
687
- {% endif %}
688
- </div>
689
- </div>
690
- <div class="form-group {% if errors.tool_qualification_cc %}has-error{% endif %}">
691
- <label class="control-label col-md-3" for="tool_qualification_cc">Reminder/expiration CC</label>
692
- <div class="col-md-5">
693
- <input type="text"
694
- id="tool_qualification_cc"
695
- name="tool_qualification_cc"
696
- class="form-control"
697
- value="{% if errors.tool_qualification_cc %}{{ errors.tool_qualification_cc.value }}{% else %}{{ tool_qualification_cc }}{% endif %}"
698
- placeholder="information@example.org" />
699
- </div>
700
- <div class="col-md-offset-3 col-md-9 help-block light-grey">
701
- {% if errors.tool_qualification_cc %}
702
- {{ errors.tool_qualification_cc.error }}
703
- {% else %}
704
- Extra email address to copy when a user's tool qualification reminder/expiration email is sent. A comma-separated list can be used.
705
- {% endif %}
706
- </div>
707
- </div>
708
- <div class="customization-separation" style="margin-bottom: 15px"></div>
709
- <div class="text-center">{% button type="save" value="Save settings" %}</div>
710
- </div>
711
- <script type="text/javascript">
626
+ <div class="text-center">{% button type="save" value="Save settings" %}</div>
627
+ </div>
628
+ <script type="text/javascript">
712
629
  $("#tool-tab-link").click(function() {setTimeout(on_tool_tab_show, 50)});
713
630
  function on_tool_tab_show()
714
631
  {
715
632
  auto_size_textarea(document.getElementById('tool_control_configuration_setting_template'))
716
633
  }
717
634
  on_tool_tab_show();
718
- </script>
719
- </form>
635
+ </script>
636
+ </form>
@@ -17,7 +17,7 @@
17
17
  History</a>
18
18
  </li>
19
19
  {% endif %}
20
- {% if show_usage_data_tab and not hide_data_history or show_usage_data_tab and user.is_any_part_of_staff %}
20
+ {% if not hide_data_history or user.is_any_part_of_staff %}
21
21
  <li style="width: 48%; text-align: center">
22
22
  <a href="#usage_data" style="padding: 10px 5px;" onclick="load_usage_data('{{ tool.id }}');">Usage Data History</a>
23
23
  </li>
@@ -50,7 +50,7 @@
50
50
  <a href="#config" onclick="load_config_history('{{ tool.id }}');">Config History</a>
51
51
  </li>
52
52
  {% endif %}
53
- {% if show_usage_data_tab and not hide_data_history or show_usage_data_tab and user.is_any_part_of_staff %}
53
+ {% if not hide_data_history or user.is_any_part_of_staff %}
54
54
  <li>
55
55
  <a href="#usage_data" onclick="load_usage_data('{{ tool.id }}');">Run Data History</a>
56
56
  </li>
@@ -98,21 +98,61 @@
98
98
  </div>
99
99
  </div>
100
100
  </form>
101
- {% if run_data_table.rows or pre_run_data_table.rows %}
101
+ {% if data_table.rows or run_data_table.rows or pre_run_data_table.rows %}
102
102
  <ul class="nav nav-tabs" id="usage-tabs">
103
+ {% if data_table.rows %}
104
+ <li class="active">
105
+ <a data-toggle="tab" href="#run-data-tab">Usage history</a>
106
+ </li>
107
+ {% endif %}
103
108
  {% if pre_run_data_table.rows %}
104
- <li class="{% if pre_run_data_table.rows %}active{% endif %}">
109
+ <li>
105
110
  <a data-toggle="tab" href="#pre-run-data-tab">Pre-Run Data</a>
106
111
  </li>
107
112
  {% endif %}
108
113
  {% if run_data_table.rows %}
109
- <li class="{% if not pre_run_data_table.rows %}active{% endif %}">
110
- <a data-toggle="tab" href="#run-data-tab">Run Data</a>
114
+ <li>
115
+ <a data-toggle="tab" href="#post-run-data-tab">Post-Run Data</a>
111
116
  </li>
112
117
  {% endif %}
113
118
  </ul>
114
119
  <div class="tab-content" style="margin-bottom: 0;">
115
- <div class="tab-pane {% if pre_run_data_table.rows %}active{% endif %}" id="pre-run-data-tab">
120
+ <div class="tab-pane active" id="run-data-tab">
121
+ <div class="col-md-12">
122
+ <div class="form-group pull-right extra-side-padding" style="padding-top: 10px">
123
+ {% button type="export" value="Export" onclick="load_usage_data('"|concat:tool_id|concat:"', 'all');" %}
124
+ </div>
125
+ </div>
126
+ <div class="panel-body">
127
+ {% if data_table.rows %}
128
+ <table class="table table-bordered table-condensed" style="margin-top: 10px">
129
+ <thead>
130
+ <tr>
131
+ {% for header in data_table.flat_headers %}<th>{{ header }}</th>{% endfor %}
132
+ </tr>
133
+ </thead>
134
+ <tbody>
135
+ {% for row in data_table.flat_rows %}
136
+ <tr>
137
+ {% for item in row %}
138
+ <td>
139
+ {% if item|class_name == "list" %}
140
+ {{ item|join:", " }}
141
+ {% else %}
142
+ {{ item|default_if_none:"" }}
143
+ {% endif %}
144
+ </td>
145
+ {% endfor %}
146
+ </tr>
147
+ {% endfor %}
148
+ </tbody>
149
+ </table>
150
+ {% else %}
151
+ <span class="italic">No run data was found between these dates</span>
152
+ {% endif %}
153
+ </div>
154
+ </div>
155
+ <div class="tab-pane" id="pre-run-data-tab">
116
156
  <div class="col-md-12">
117
157
  <div class="form-group pull-right extra-side-padding" style="padding-top: 10px">
118
158
  {% button type="export" value="Export" onclick="load_usage_data('"|concat:tool_id|concat:"', 'pre-run');" %}
@@ -147,7 +187,7 @@
147
187
  {% endif %}
148
188
  </div>
149
189
  </div>
150
- <div class="tab-pane {% if not pre_run_data_table.rows %}active{% endif %}" id="run-data-tab">
190
+ <div class="tab-pane" id="post-run-data-tab">
151
191
  <div class="col-md-12">
152
192
  <div class="form-group pull-right extra-side-padding" style="padding-top: 10px">
153
193
  {% button type="export" value="Export" onclick="load_usage_data('"|concat:tool_id|concat:"', 'run');" %}
@@ -7,7 +7,7 @@ from django.utils import timezone
7
7
 
8
8
  from NEMO.models import Account, EmailLog, Project, Qualification, Tool, UsageEvent, User
9
9
  from NEMO.tests.test_utilities import NEMOTestCaseMixin
10
- from NEMO.views.customization import EmailsCustomization, ToolCustomization
10
+ from NEMO.views.customization import EmailsCustomization
11
11
  from NEMO.views.timed_services import do_manage_tool_qualifications
12
12
 
13
13
 
@@ -45,7 +45,8 @@ class ToolQualificationTestCase(NEMOTestCaseMixin, TestCase):
45
45
  )
46
46
 
47
47
  # Never used days set but not regular days
48
- ToolCustomization.set("tool_qualification_expiration_never_used_days", 3)
48
+ self.tool.qualification_expiration_never_used_days = 3
49
+ self.tool.save()
49
50
  EmailsCustomization.set("user_office_email_address", "user_office@example.com")
50
51
  # Trigger the expiration timed service
51
52
  do_manage_tool_qualifications()
@@ -59,7 +60,8 @@ class ToolQualificationTestCase(NEMOTestCaseMixin, TestCase):
59
60
  Qualification.objects.create(tool=self.tool, user=self.user, qualified_on=qualification_date)
60
61
 
61
62
  # Expiration days are set but never used days are not
62
- ToolCustomization.set("tool_qualification_expiration_days", 3)
63
+ self.tool.qualification_expiration_days = 3
64
+ self.tool.save()
63
65
  EmailsCustomization.set("user_office_email_address", "user_office@example.com")
64
66
  # Trigger the expiration timed service
65
67
  do_manage_tool_qualifications()
@@ -72,8 +74,9 @@ class ToolQualificationTestCase(NEMOTestCaseMixin, TestCase):
72
74
  qualification_date = datetime.today() - timedelta(days=3)
73
75
  Qualification.objects.create(tool=self.tool, user=self.user, qualified_on=qualification_date)
74
76
 
75
- ToolCustomization.set("tool_qualification_expiration_never_used_days", 3)
76
- ToolCustomization.set("tool_qualification_expiration_days", 3)
77
+ self.tool.qualification_expiration_days = 3
78
+ self.tool.qualification_expiration_never_used_days = 3
79
+ self.tool.save()
77
80
  # Trigger the expiration timed service
78
81
  do_manage_tool_qualifications()
79
82
  # Qualification was NOT removed
@@ -84,8 +87,9 @@ class ToolQualificationTestCase(NEMOTestCaseMixin, TestCase):
84
87
  qualification_date = datetime.today() - timedelta(days=3)
85
88
  Qualification.objects.create(tool=self.tool, user=self.user, qualified_on=qualification_date)
86
89
 
87
- ToolCustomization.set("tool_qualification_expiration_never_used_days", 3)
88
- ToolCustomization.set("tool_qualification_expiration_days", 3)
90
+ self.tool.qualification_expiration_days = 3
91
+ self.tool.qualification_expiration_never_used_days = 3
92
+ self.tool.save()
89
93
  EmailsCustomization.set("user_office_email_address", "user_office@example.com")
90
94
  # Trigger the expiration timed service
91
95
  do_manage_tool_qualifications()
@@ -96,15 +100,10 @@ class ToolQualificationTestCase(NEMOTestCaseMixin, TestCase):
96
100
  mock_exist.return_value = True
97
101
  mock_open.return_value = ContentFile(b"Email template", name="template")
98
102
 
99
- # Tool is exempt
100
- self.tool._qualifications_never_expire = True
101
- self.tool.save()
102
-
103
103
  qualification_date = datetime.today() - timedelta(days=3)
104
104
  Qualification.objects.create(tool=self.tool, user=self.user, qualified_on=qualification_date)
105
105
 
106
- ToolCustomization.set("tool_qualification_expiration_never_used_days", 3)
107
- ToolCustomization.set("tool_qualification_expiration_days", 3)
106
+ # Tool is exempt, meaning no qualification expiration need to be added
108
107
  EmailsCustomization.set("user_office_email_address", "user_office@example.com")
109
108
  # Trigger the expiration timed service
110
109
  do_manage_tool_qualifications()
@@ -121,7 +120,8 @@ class ToolQualificationTestCase(NEMOTestCaseMixin, TestCase):
121
120
  user=self.user, operator=self.user, tool=self.tool, project=self.project, start=usage_date
122
121
  )
123
122
 
124
- ToolCustomization.set("tool_qualification_expiration_days", 3)
123
+ self.tool.qualification_expiration_days = 3
124
+ self.tool.save()
125
125
  EmailsCustomization.set("user_office_email_address", "user_office@example.com")
126
126
  # Trigger the expiration timed service
127
127
  do_manage_tool_qualifications()
@@ -134,7 +134,8 @@ class ToolQualificationTestCase(NEMOTestCaseMixin, TestCase):
134
134
  qualification_date = datetime.today() - timedelta(days=2)
135
135
  Qualification.objects.create(tool=self.tool, user=self.user, qualified_on=qualification_date)
136
136
 
137
- ToolCustomization.set("tool_qualification_expiration_never_used_days", 3)
137
+ self.tool.qualification_expiration_never_used_days = 3
138
+ self.tool.save()
138
139
  EmailsCustomization.set("user_office_email_address", "user_office@example.com")
139
140
  # Trigger the expiration timed service
140
141
  do_manage_tool_qualifications()
@@ -151,7 +152,8 @@ class ToolQualificationTestCase(NEMOTestCaseMixin, TestCase):
151
152
  user=self.user, operator=self.user, tool=self.tool, project=self.project, start=usage_date
152
153
  )
153
154
 
154
- ToolCustomization.set("tool_qualification_expiration_days", 3)
155
+ self.tool.qualification_expiration_days = 3
156
+ self.tool.save()
155
157
  EmailsCustomization.set("user_office_email_address", "user_office@example.com")
156
158
  # Trigger the expiration timed service
157
159
  do_manage_tool_qualifications()
@@ -172,7 +174,8 @@ class ToolQualificationTestCase(NEMOTestCaseMixin, TestCase):
172
174
  user=self.user, operator=self.user, tool=self.tool, project=self.project, start=usage_date
173
175
  )
174
176
 
175
- ToolCustomization.set("tool_qualification_expiration_days", 3)
177
+ self.tool.qualification_expiration_days = 3
178
+ self.tool.save()
176
179
  EmailsCustomization.set("user_office_email_address", "user_office@example.com")
177
180
  # Trigger the expiration timed service
178
181
  do_manage_tool_qualifications()
@@ -189,7 +192,8 @@ class ToolQualificationTestCase(NEMOTestCaseMixin, TestCase):
189
192
  qualification_date = datetime.today() - timedelta(days=3)
190
193
  Qualification.objects.create(tool=self.tool, user=self.user, qualified_on=qualification_date)
191
194
 
192
- ToolCustomization.set("tool_qualification_expiration_never_used_days", 3)
195
+ self.tool.qualification_expiration_never_used_days = 3
196
+ self.tool.save()
193
197
  EmailsCustomization.set("user_office_email_address", "user_office@example.com")
194
198
  # Trigger the expiration timed service
195
199
  do_manage_tool_qualifications()
@@ -210,9 +214,10 @@ class ToolQualificationTestCase(NEMOTestCaseMixin, TestCase):
210
214
  user=self.user, operator=self.user, tool=self.tool, project=self.project, start=usage_date
211
215
  )
212
216
 
213
- ToolCustomization.set("tool_qualification_expiration_days", 3)
217
+ self.tool.qualification_expiration_days = 3
218
+ self.tool.qualification_notification_email = "qualif_cc@example.com"
219
+ self.tool.save()
214
220
  EmailsCustomization.set("user_office_email_address", "user_office@example.com")
215
- ToolCustomization.set("tool_qualification_cc", "qualif_cc@example.com")
216
221
  # Set alternate email for user
217
222
  prefs = self.user.get_preferences()
218
223
  prefs.email_alternate = "user.alternate@example.com"
@@ -239,9 +244,10 @@ class ToolQualificationTestCase(NEMOTestCaseMixin, TestCase):
239
244
  qualification_date = datetime.today() - timedelta(days=20)
240
245
  Qualification.objects.create(tool=self.tool, user=self.user, qualified_on=qualification_date)
241
246
 
242
- ToolCustomization.set("tool_qualification_expiration_never_used_days", 3)
247
+ self.tool.qualification_expiration_never_used_days = 3
248
+ self.tool.qualification_notification_email = "qualif_cc@example.com"
249
+ self.tool.save()
243
250
  EmailsCustomization.set("user_office_email_address", "user_office@example.com")
244
- ToolCustomization.set("tool_qualification_cc", "qualif_cc@example.com")
245
251
  # Set alternate email for user
246
252
  prefs = self.user.get_preferences()
247
253
  prefs.email_alternate = "user.alternate@example.com"
@@ -273,9 +279,10 @@ class ToolQualificationTestCase(NEMOTestCaseMixin, TestCase):
273
279
  user=self.user, operator=self.user, tool=self.tool, project=self.project, start=usage_date
274
280
  )
275
281
 
276
- ToolCustomization.set("tool_qualification_expiration_days", 3)
277
282
  # Set reminder 2 days before expiration
278
- ToolCustomization.set("tool_qualification_reminder_days", 2)
283
+ self.tool.qualification_expiration_days = 3
284
+ self.tool.qualification_reminder_days = "3,2"
285
+ self.tool.save()
279
286
  # Trigger the expiration timed service
280
287
  do_manage_tool_qualifications()
281
288
  # Qualification was NOT removed (3 days disqualified, but only 2 days since qualification)
@@ -292,9 +299,10 @@ class ToolQualificationTestCase(NEMOTestCaseMixin, TestCase):
292
299
  Qualification.objects.create(tool=self.tool, user=self.user, qualified_on=qualification_date)
293
300
  EmailsCustomization.set("user_office_email_address", "user_office@example.com")
294
301
 
295
- ToolCustomization.set("tool_qualification_expiration_never_used_days", 3)
296
302
  # Set reminder 2 days before expiration
297
- ToolCustomization.set("tool_qualification_reminder_days", 2)
303
+ self.tool.qualification_expiration_never_used_days = 3
304
+ self.tool.qualification_reminder_days = "3,2"
305
+ self.tool.save()
298
306
  # Trigger the expiration timed service
299
307
  do_manage_tool_qualifications()
300
308
  # Qualification was NOT removed (3 days disqualified, but only 2 days since qualification)
@@ -315,9 +323,10 @@ class ToolQualificationTestCase(NEMOTestCaseMixin, TestCase):
315
323
  user=self.user, operator=self.user, tool=self.tool, project=self.project, start=usage_date
316
324
  )
317
325
 
318
- ToolCustomization.set("tool_qualification_expiration_days", 3)
319
326
  # Set reminder 1 day before expiration
320
- ToolCustomization.set("tool_qualification_reminder_days", 1)
327
+ self.tool.qualification_expiration_days = 3
328
+ self.tool.qualification_reminder_days = "1"
329
+ self.tool.save()
321
330
  # Trigger the expiration timed service
322
331
  do_manage_tool_qualifications()
323
332
  # Qualification was NOT removed (3 days disqualified, but only 2 days since qualification)
@@ -334,9 +343,10 @@ class ToolQualificationTestCase(NEMOTestCaseMixin, TestCase):
334
343
  Qualification.objects.create(tool=self.tool, user=self.user, qualified_on=qualification_date)
335
344
  EmailsCustomization.set("user_office_email_address", "user_office@example.com")
336
345
 
337
- ToolCustomization.set("tool_qualification_expiration_never_used_days", 3)
338
346
  # Set reminder 1 day before expiration
339
- ToolCustomization.set("tool_qualification_reminder_days", 1)
347
+ self.tool.qualification_expiration_never_used_days = 3
348
+ self.tool.qualification_reminder_days = "1"
349
+ self.tool.save()
340
350
  # Trigger the expiration timed service
341
351
  do_manage_tool_qualifications()
342
352
  # Qualification was NOT removed (3 days disqualified, but only 2 days since qualification)