clinicedc 2.0.6__py3-none-any.whl → 2.0.8__py3-none-any.whl

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.

Potentially problematic release.


This version of clinicedc might be problematic. Click here for more details.

Files changed (495) hide show
  1. {clinicedc-2.0.6.dist-info → clinicedc-2.0.8.dist-info}/METADATA +2 -2
  2. {clinicedc-2.0.6.dist-info → clinicedc-2.0.8.dist-info}/RECORD +489 -441
  3. {clinicedc-2.0.6.dist-info → clinicedc-2.0.8.dist-info}/WHEEL +1 -1
  4. edc_action_item/action.py +1 -1
  5. edc_action_item/action_item_notification.py +2 -2
  6. edc_action_item/auths.py +37 -32
  7. edc_action_item/create_action_item.py +1 -1
  8. edc_action_item/decorators.py +1 -1
  9. edc_action_item/migrations/0001_initial.py +21 -22
  10. edc_action_item/migrations/0006_auto_20180707_1659.py +4 -4
  11. edc_action_item/migrations/0008_auto_20180809_0303.py +4 -4
  12. edc_action_item/migrations/0015_auto_20190114_0250.py +4 -4
  13. edc_action_item/migrations/0017_auto_20190305_0123.py +11 -30
  14. edc_action_item/migrations/0030_edcpermissions.py +3 -2
  15. edc_action_item/migrations/0039_alter_actionitem_auto_created_comment_and_more.py +398 -0
  16. edc_action_item/migrations/0040_alter_actionitem_report_datetime_and_more.py +34 -0
  17. edc_action_item/models/action_item.py +9 -4
  18. edc_action_item/models/action_model_mixin.py +5 -6
  19. edc_action_item/models/reference.py +2 -2
  20. edc_action_item/models/signals.py +22 -23
  21. edc_action_item/post_migrate_signals.py +1 -1
  22. edc_action_item/send_email.py +0 -85
  23. edc_action_item/site_action_items.py +5 -9
  24. edc_action_item/utils.py +3 -3
  25. edc_adherence/migrations/0005_alter_nonadherencereasons_extra_value_and_more.py +36 -0
  26. edc_adherence/model_mixins.py +1 -1
  27. edc_adverse_event/auths.py +55 -51
  28. edc_adverse_event/migrations/0001_initial.py +5 -4
  29. edc_adverse_event/migrations/0002_auto_20190802_0059.py +3 -2
  30. edc_adverse_event/migrations/0008_auto_20220825_0451.py +3 -2
  31. edc_adverse_event/migrations/0009_auto_20220907_0157.py +3 -2
  32. edc_adverse_event/migrations/0016_alter_aeactionclassification_device_created_and_more.py +285 -0
  33. edc_adverse_event/model_mixins/ae_followup/ae_followup_fields_model_mixin.py +2 -2
  34. edc_adverse_event/model_mixins/ae_initial/ae_initial_fields_model_mixin.py +6 -5
  35. edc_adverse_event/model_mixins/ae_special_interest/aesi_fields_model_mixin.py +2 -2
  36. edc_adverse_event/model_mixins/ae_susar/ae_susar_fields_model_mixin.py +2 -2
  37. edc_adverse_event/model_mixins/ae_tmg/ae_tmg_fields_model_mixin.py +15 -11
  38. edc_adverse_event/model_mixins/ae_tmg/ae_tmg_methods_model_mixin.py +2 -4
  39. edc_adverse_event/model_mixins/death_report/death_report_model_mixin.py +5 -4
  40. edc_adverse_event/model_mixins/death_report/death_report_tmg_model_mixin.py +6 -3
  41. edc_adverse_event/model_mixins/death_report/simple_death_report_model_mixin.py +2 -2
  42. edc_adverse_event/model_mixins/hospitaization/hospitalization_model_mixin.py +4 -3
  43. edc_adverse_event/modeladmin_mixins/death_report_admin_mixin.py +3 -3
  44. edc_adverse_event/models/signals.py +7 -7
  45. edc_adverse_event/templatetags/edc_adverse_event_extras.py +5 -4
  46. edc_adverse_event/view_mixins/ae/ae_listboard_view_mixin.py +3 -5
  47. edc_adverse_event/view_mixins/ae/death_report_listboard_view_mixin.py +6 -8
  48. edc_adverse_event/view_mixins/tmg/tmg_ae_listboard_view_mixin.py +2 -2
  49. edc_adverse_event/views/tmg/summary_listboard_view.py +3 -2
  50. edc_appointment/admin/appointment_admin.py +2 -2
  51. edc_appointment/admin/list_filters.py +2 -2
  52. edc_appointment/auths.py +14 -10
  53. edc_appointment/creators/appointment_creator.py +1 -1
  54. edc_appointment/creators/appointments_creator.py +1 -1
  55. edc_appointment/form_validators/appointment_form_validator.py +108 -82
  56. edc_appointment/migrations/0003_auto_20161127_2226.py +5 -6
  57. edc_appointment/migrations/0006_auto_20170106_2118.py +5 -5
  58. edc_appointment/migrations/0018_auto_20190305_0123.py +5 -12
  59. edc_appointment/migrations/0050_alter_appointment_appt_type_and_more.py +220 -0
  60. edc_appointment/model_mixins/appointment_fields_model_mixin.py +1 -2
  61. edc_appointment/model_mixins/appointment_methods_model_mixin.py +2 -3
  62. edc_appointment/model_mixins/appointment_model_mixin.py +31 -28
  63. edc_appointment/model_mixins/window_period_model_mixin.py +6 -7
  64. edc_appointment/models/appointment.py +1 -1
  65. edc_appointment/models/signals.py +44 -35
  66. edc_appointment/utils.py +19 -24
  67. edc_appointment/view_utils/appointment_button.py +2 -2
  68. edc_auth/admin/user_admin.py +1 -1
  69. edc_auth/auth_objects/__init__.py +2 -20
  70. edc_auth/auth_objects/default_groups.py +13 -11
  71. edc_auth/auth_objects/default_roles.py +26 -24
  72. edc_auth/auth_updater/auth_updater.py +13 -2
  73. edc_auth/auth_updater/group_updater.py +12 -10
  74. edc_auth/auth_updater/role_updater.py +2 -2
  75. edc_auth/constants.py +10 -0
  76. edc_auth/import_users.py +3 -3
  77. edc_auth/migrations/0001_squashed_0033_alter_userprofile_is_multisite_viewer.py +5 -5
  78. edc_auth/migrations/0012_auto_20191026_0034.py +3 -2
  79. edc_auth/migrations/0013_auto_20191026_0055.py +3 -2
  80. edc_auth/migrations/0025_permissions.py +3 -2
  81. edc_auth/migrations/0035_alter_edcpermissions_device_created_and_more.py +85 -0
  82. edc_auth/models/user_profile.py +14 -11
  83. edc_auth/post_migrate_signals.py +1 -1
  84. edc_auth/site_auths.py +80 -67
  85. edc_consent/actions.py +4 -5
  86. edc_consent/auths.py +18 -12
  87. edc_consent/migrations/0001_initial.py +3 -2
  88. edc_consent/migrations/0006_alter_edcpermissions_device_created_and_more.py +49 -0
  89. edc_consent/model_mixins/consent_extension_model_mixin.py +4 -5
  90. edc_consent/model_mixins/requires_consent_fields_model_mixin.py +2 -2
  91. edc_consent/utils.py +1 -1
  92. edc_constants/constants.py +1 -0
  93. edc_crf/auths.py +5 -0
  94. edc_crf/migrations/0001_initial.py +3 -2
  95. edc_crf/migrations/0009_alter_crfstatus_device_created_and_more.py +54 -0
  96. edc_dashboard/auths.py +10 -6
  97. edc_dashboard/migrations/0001_initial.py +3 -2
  98. edc_dashboard/migrations/0006_alter_edcpermissions_device_created_and_more.py +49 -0
  99. edc_dashboard/templatetags/edc_dashboard_extras.py +3 -2
  100. edc_dashboard/url_config.py +92 -83
  101. edc_dashboard/url_names.py +4 -4
  102. edc_dashboard/view_mixins/url_request_context_mixin.py +6 -5
  103. edc_data_manager/action_items.py +4 -6
  104. edc_data_manager/admin/actions.py +5 -5
  105. edc_data_manager/admin/data_query_admin.py +12 -11
  106. edc_data_manager/auths.py +37 -34
  107. edc_data_manager/handlers/handlers.py +6 -7
  108. edc_data_manager/migrations/0001_initial.py +19 -19
  109. edc_data_manager/migrations/0025_edcpermissions.py +3 -2
  110. edc_data_manager/migrations/0040_alter_datadictionary_device_created_and_more.py +327 -0
  111. edc_data_manager/migrations/0041_alter_dataquery_dm_user_and_more.py +164 -0
  112. edc_data_manager/models/data_query.py +5 -5
  113. edc_data_manager/models/model_mixins.py +8 -8
  114. edc_data_manager/rule/query_rule_wrapper.py +7 -7
  115. edc_data_manager/rule/rule_runner.py +4 -3
  116. edc_document_status/model_mixins.py +1 -1
  117. edc_egfr/egfr.py +11 -7
  118. edc_egfr/model_mixins/egfr_model_mixin.py +3 -7
  119. edc_export/admin/data_request_admin.py +2 -2
  120. edc_export/archive_exporter.py +7 -5
  121. edc_export/auths.py +32 -28
  122. edc_export/files_archiver.py +3 -2
  123. edc_export/migrations/0001_initial.py +26 -26
  124. edc_export/migrations/0004_auto_20190305_0123.py +25 -72
  125. edc_export/migrations/0013_edcpermissions.py +3 -2
  126. edc_export/migrations/0022_alter_datarequest_description_and_more.py +611 -0
  127. edc_export/migrations/0023_alter_datarequesthistory_archive_filename_and_more.py +29 -0
  128. edc_export/model_exporter/file_history_updater.py +10 -10
  129. edc_export/model_exporter/model_exporter.py +17 -15
  130. edc_export/model_exporter/object_history_helpers.py +2 -2
  131. edc_export/models/data_request_history.py +4 -4
  132. edc_export/utils.py +10 -15
  133. edc_facility/auths.py +8 -3
  134. edc_facility/facility.py +16 -22
  135. edc_facility/import_holidays.py +13 -13
  136. edc_facility/migrations/0005_healthfacility_healthfacilitytypes_and_more.py +8 -7
  137. edc_facility/migrations/0016_alter_healthfacility_device_created_and_more.py +139 -0
  138. edc_facility/migrations/0017_alter_healthfacility_gps_and_more.py +54 -0
  139. edc_facility/model_mixins.py +5 -5
  140. edc_form_label/custom_label_condition.py +11 -8
  141. edc_form_label/form_label.py +1 -1
  142. edc_form_runners/auths.py +11 -6
  143. edc_form_runners/form_runner.py +3 -5
  144. edc_form_runners/migrations/0001_initial.py +3 -2
  145. edc_form_runners/migrations/0005_alter_issue_device_created_and_more.py +49 -0
  146. edc_form_validators/applicable_field_validator.py +7 -6
  147. edc_form_validators/base_form_validator.py +8 -9
  148. edc_form_validators/other_specify_field_validator.py +2 -8
  149. edc_form_validators/required_field_validator.py +19 -16
  150. edc_identifier/migrations/0001_squashed_0018_auto_20180128_1054.py +3 -3
  151. edc_identifier/migrations/0002_auto_20190305_0123.py +3 -6
  152. edc_identifier/migrations/0006_auto_20161127_2226.py +15 -15
  153. edc_identifier/migrations/0007_auto_20161204_2227.py +3 -3
  154. edc_identifier/migrations/0009_auto_20161221_2323.py +3 -5
  155. edc_identifier/migrations/0010_auto_20170112_0602.py +17 -17
  156. edc_identifier/migrations/0011_alter_identifiermodel_device_created_and_more.py +79 -0
  157. edc_identifier/model_mixins.py +1 -1
  158. edc_identifier/models.py +9 -9
  159. edc_identifier/research_identifier.py +11 -10
  160. edc_identifier/simple_identifier.py +9 -5
  161. edc_identifier/subject_identifier.py +3 -2
  162. edc_lab/auths.py +26 -23
  163. edc_lab/lab/aliquot_creator.py +5 -8
  164. edc_lab/lab/primary_aliquot.py +14 -5
  165. edc_lab/migrations/0001_initial.py +29 -29
  166. edc_lab/migrations/0008_auto_20170921_0719.py +3 -3
  167. edc_lab/migrations/0010_auto_20171127_1541.py +15 -15
  168. edc_lab/migrations/0012_auto_20180114_1438.py +3 -3
  169. edc_lab/migrations/0019_auto_20190305_0123.py +43 -127
  170. edc_lab/migrations/0036_alter_aliquot_comment_alter_aliquot_device_created_and_more.py +1139 -0
  171. edc_lab/migrations/0037_alter_historicalorder_order_datetime_and_more.py +31 -0
  172. edc_lab/model_mixins/aliquot/aliquot_identifier_model_mixin.py +2 -2
  173. edc_lab/model_mixins/aliquot/aliquot_model_mixin.py +2 -2
  174. edc_lab/model_mixins/panel_model_mixin.py +18 -7
  175. edc_lab/model_mixins/requisition/crf_with_requisition_model_mixin.py +2 -4
  176. edc_lab/model_mixins/requisition/requisition_model_mixin.py +13 -16
  177. edc_lab/model_mixins/requisition/requisition_verify_model_mixin.py +1 -1
  178. edc_lab/model_mixins/result/result_item_model_mixin.py +4 -4
  179. edc_lab/model_mixins/shipping/manifest_model_mixin.py +4 -5
  180. edc_lab/model_mixins/shipping/verify_model_mixin.py +4 -6
  181. edc_lab/models/aliquot.py +2 -2
  182. edc_lab/models/box.py +1 -1
  183. edc_lab/models/box_item.py +6 -7
  184. edc_lab/models/manifest/manifest.py +3 -3
  185. edc_lab/models/manifest/manifest_item.py +7 -7
  186. edc_lab/models/manifest/shipper.py +3 -4
  187. edc_lab/models/order.py +6 -4
  188. edc_lab/models/panel.py +4 -4
  189. edc_lab/models/result.py +2 -2
  190. edc_lab/models/result_item.py +2 -2
  191. edc_lab_dashboard/auths.py +16 -11
  192. edc_lab_dashboard/migrations/0001_initial.py +3 -2
  193. edc_lab_dashboard/migrations/0005_alter_edcpermissions_device_created_and_more.py +49 -0
  194. edc_lab_dashboard/views/action_views/receive_view.py +2 -2
  195. edc_lab_dashboard/views/action_views/verify_box_item_view.py +2 -2
  196. edc_lab_results/calculate_missing.py +8 -8
  197. edc_lab_results/form_validator_mixins/blood_results_form_validator_mixin.py +2 -2
  198. edc_lab_results/get_summary.py +26 -25
  199. edc_lab_results/model_mixins/blood_result_model_mixin.py +9 -7
  200. edc_lab_results/model_mixins/fbg_model_mixin.py +3 -3
  201. edc_lab_results/model_mixins/glucose_model_mixin.py +3 -3
  202. edc_lab_results/model_mixins/hba1c_model_mixin.py +3 -3
  203. edc_label/auths.py +6 -1
  204. edc_label/label_template.py +8 -8
  205. edc_label/migrations/0001_initial.py +3 -2
  206. edc_label/migrations/0007_alter_zpllabeltemplates_device_created_and_more.py +49 -0
  207. edc_list_data/list_model_maker.py +2 -2
  208. edc_list_data/load_list_data.py +11 -14
  209. edc_list_data/load_model_data.py +3 -3
  210. edc_list_data/model_mixins.py +12 -4
  211. edc_list_data/post_migrate_signals.py +1 -1
  212. edc_list_data/preload_data.py +4 -4
  213. edc_list_data/row.py +1 -1
  214. edc_list_data/site_list_data.py +6 -5
  215. edc_listboard/migrations/0001_initial.py +3 -2
  216. edc_listboard/migrations/0007_alter_listboard_device_created_and_more.py +49 -0
  217. edc_locator/auths.py +18 -13
  218. edc_locator/migrations/0001_initial.py +7 -7
  219. edc_locator/migrations/0018_auto_20190305_0123.py +5 -12
  220. edc_locator/migrations/0040_alter_historicalsubjectlocator_action_identifier_and_more.py +187 -0
  221. edc_locator/migrations/0041_alter_historicalsubjectlocator_report_datetime_and_more.py +27 -0
  222. edc_locator/model_mixins/locator_model_mixin.py +2 -2
  223. edc_locator/model_mixins/subject_contact_fields_mixin.py +1 -1
  224. edc_locator/modeladmin_mixins.py +5 -4
  225. edc_ltfu/model_mixins.py +7 -5
  226. edc_metadata/auths.py +11 -7
  227. edc_metadata/metadata/metadata.py +1 -1
  228. edc_metadata/metadata_rules/crf/crf_rule.py +1 -1
  229. edc_metadata/metadata_rules/decorators.py +1 -1
  230. edc_metadata/metadata_rules/metadata_rule_evaluator.py +5 -3
  231. edc_metadata/metadata_rules/rule.py +2 -3
  232. edc_metadata/metadata_rules/rule_evaluator.py +1 -1
  233. edc_metadata/migrations/0002_auto_20161127_2226.py +5 -5
  234. edc_metadata/migrations/0005_auto_20170112_0602.py +5 -5
  235. edc_metadata/migrations/0011_auto_20190305_0123.py +5 -12
  236. edc_metadata/migrations/0031_alter_crfmetadata_device_created_and_more.py +120 -0
  237. edc_metadata/model_mixins/updates/updates_crf_metadata_model_mixin.py +7 -4
  238. edc_metadata/model_mixins/updates/updates_requisition_metadata_model_mixin.py +5 -2
  239. edc_metadata/models/crf_metadata.py +5 -5
  240. edc_metadata/models/crf_metadata_model_mixin.py +4 -5
  241. edc_metadata/models/requisition_metadata.py +6 -6
  242. edc_metadata/models/signals.py +10 -11
  243. edc_metadata/views/refresh_metadata_actions_view.py +3 -3
  244. edc_model/models/address_mixin.py +6 -6
  245. edc_model/models/fields/initials_field.py +2 -1
  246. edc_model/models/historical_records.py +2 -9
  247. edc_model/models/url_model_mixin.py +2 -2
  248. edc_model/validators/date.py +7 -8
  249. edc_model_admin/list_filters/future_date_list_filter.py +3 -3
  250. edc_model_admin/list_filters/past_date_list_filter.py +3 -3
  251. edc_model_admin/mixins/model_admin_protect_pii_mixin.py +4 -5
  252. edc_model_fields/fields/other_charfield.py +2 -2
  253. edc_navbar/auths.py +18 -13
  254. edc_navbar/migrations/0004_auto_20220825_0451.py +3 -2
  255. edc_navbar/migrations/0009_alter_edcpermissions_device_created_and_more.py +49 -0
  256. edc_notification/auths.py +9 -4
  257. edc_notification/migrations/0001_initial.py +3 -3
  258. edc_notification/migrations/0004_auto_20190305_0123.py +3 -6
  259. edc_notification/migrations/0011_alter_notification_device_created_and_more.py +59 -0
  260. edc_notification/models/notification.py +1 -1
  261. edc_notification/notification/graded_event_notification.py +2 -2
  262. edc_notification/notification/model_notification.py +3 -30
  263. edc_notification/notification/new_model_notification.py +1 -1
  264. edc_notification/notification/notification.py +12 -12
  265. edc_notification/notification/updated_model_notification.py +2 -2
  266. edc_offstudy/auths.py +12 -7
  267. edc_offstudy/migrations/0001_initial.py +4 -4
  268. edc_offstudy/migrations/0002_auto_20180921_0434.py +4 -4
  269. edc_offstudy/migrations/0005_auto_20190305_0123.py +5 -12
  270. edc_offstudy/migrations/0023_alter_historicalsubjectoffstudy_action_identifier_and_more.py +188 -0
  271. edc_offstudy/migrations/0024_alter_historicalsubjectoffstudy_offstudy_datetime_and_more.py +43 -0
  272. edc_offstudy/model_mixins/offstudy_model_mixin.py +3 -2
  273. edc_pdutils/df_exporters/csv_exporter.py +33 -37
  274. edc_pdutils/df_exporters/csv_model_exporter.py +7 -3
  275. edc_pdutils/migrations/0001_initial.py +8 -8
  276. edc_pharmacy/admin/prescription/rx_refill_admin.py +4 -3
  277. edc_pharmacy/admin/reports/stock_availability_admin.py +5 -6
  278. edc_pharmacy/auths.py +19 -15
  279. edc_pharmacy/migrations/0001_initial.py +64 -63
  280. edc_pharmacy/migrations/0015_auto_20220913_2139.py +26 -26
  281. edc_pharmacy/migrations/0024_allocation_assignment_containerunits_dispense_and_more.py +81 -86
  282. edc_pharmacy/migrations/0037_remove_historicalstock_confirmed_at_site_by_and_more.py +5 -5
  283. edc_pharmacy/migrations/0039_remove_dispense_registered_subject_and_more.py +7 -8
  284. edc_pharmacy/migrations/0049_remove_stocktransferconfirmation_stock_and_more.py +12 -12
  285. edc_pharmacy/migrations/0050_remove_stocktransferconfirmation2_location_and_more.py +5 -5
  286. edc_pharmacy/migrations/0051_alter_historicalstocktransferconfirmationitem_options_and_more.py +3 -4
  287. edc_pharmacy/migrations/0053_alter_location_managers_alter_historicalstock_lot_and_more.py +3 -3
  288. edc_pharmacy/migrations/0057_scanduplicates.py +3 -3
  289. edc_pharmacy/migrations/0060_alter_container_max_per_subject_and_more.py +13 -15
  290. edc_pharmacy/migrations/0068_stockout.py +2 -3
  291. edc_pharmacy/migrations/0076_historicalstockadjustment_stockadjustment.py +5 -5
  292. edc_pharmacy/migrations/0077_historicalstockadjustment_adjustment_datetime_and_more.py +3 -4
  293. edc_pharmacy/migrations/0081_historicalconfirmation_confirmation.py +8 -8
  294. edc_pharmacy/migrations/0084_confirmationatsiteitem_and_more.py +0 -2
  295. edc_pharmacy/migrations/0089_alter_allocation_allocated_by_and_more.py +3284 -0
  296. edc_pharmacy/migrations/0090_alter_allocation_allocation_datetime_and_more.py +227 -0
  297. edc_pharmacy/model_mixins/study_medication_refill_model_mixin.py +2 -2
  298. edc_pharmacy/models/medication/formulation.py +5 -7
  299. edc_pharmacy/models/medication/medication.py +3 -3
  300. edc_pharmacy/models/model_mixins.py +10 -11
  301. edc_pharmacy/models/prescription/rx.py +13 -12
  302. edc_pharmacy/models/prescription/rx_refill.py +0 -1
  303. edc_pharmacy/models/stock/allocation.py +3 -3
  304. edc_pharmacy/models/stock/confirmation.py +3 -3
  305. edc_pharmacy/models/stock/confirmation_at_site.py +3 -2
  306. edc_pharmacy/models/stock/confirmation_at_site_item.py +3 -4
  307. edc_pharmacy/models/stock/dispense.py +5 -6
  308. edc_pharmacy/models/stock/dispense_item.py +2 -2
  309. edc_pharmacy/models/stock/location.py +3 -4
  310. edc_pharmacy/models/stock/lot.py +6 -7
  311. edc_pharmacy/models/stock/order.py +1 -1
  312. edc_pharmacy/models/stock/receive.py +3 -3
  313. edc_pharmacy/models/stock/receive_item.py +4 -4
  314. edc_pharmacy/models/stock/repack_request.py +2 -2
  315. edc_pharmacy/models/stock/stock.py +12 -18
  316. edc_pharmacy/models/stock/stock_adjustment.py +4 -4
  317. edc_pharmacy/models/stock/stock_request.py +2 -2
  318. edc_pharmacy/models/stock/stock_request_item.py +2 -2
  319. edc_pharmacy/models/stock/stock_transfer.py +3 -3
  320. edc_pharmacy/models/stock/stock_transfer_item.py +2 -2
  321. edc_pharmacy/models/stock/storage_bin.py +3 -4
  322. edc_pharmacy/models/stock/storage_bin_item.py +2 -2
  323. edc_pharmacy/models/stock/supplier.py +3 -4
  324. edc_pharmacy/models/storage/box.py +2 -2
  325. edc_pharmacy/models/storage/items/container_model_mixin.py +3 -4
  326. edc_pharmacy/models/storage/items/pill_bottle_model_mixin.py +2 -2
  327. edc_pharmacy/models/storage/items/subject_pill_bottle.py +1 -1
  328. edc_pharmacy/models/storage/room.py +2 -2
  329. edc_pharmacy/models/storage/shelf.py +2 -2
  330. edc_pharmacy/models/storage/utils.py +1 -1
  331. edc_pharmacy/prescribe/create_prescription.py +3 -3
  332. edc_pharmacy/utils/allocate_stock.py +2 -3
  333. edc_pharmacy/utils/confirm_stock.py +3 -4
  334. edc_pharmacy/utils/confirm_stock_at_site.py +4 -5
  335. edc_pharmacy/utils/dispense.py +3 -4
  336. edc_pharmacy/utils/process_repack_request.py +4 -5
  337. edc_pharmacy/utils/stock_request/bulk_create_stock_request_items.py +2 -3
  338. edc_pharmacy/utils/transfer_stock.py +2 -3
  339. edc_pharmacy/views/add_to_storage_bin_view.py +2 -2
  340. edc_pharmacy/views/allocate_to_subject_view.py +2 -2
  341. edc_pharmacy/views/confirmation_at_site_view.py +6 -9
  342. edc_pharmacy/views/dispense_view.py +2 -2
  343. edc_pharmacy/views/move_to_storage_bin_view.py +2 -3
  344. edc_pharmacy/views/print_labels_view.py +2 -2
  345. edc_prn/admin_site.py +5 -0
  346. edc_prn/prn.py +10 -11
  347. edc_prn/urls.py +11 -0
  348. edc_protocol/research_protocol_config.py +2 -3
  349. edc_protocol_incident/action_items.py +4 -4
  350. edc_protocol_incident/auths.py +27 -20
  351. edc_protocol_incident/migrations/0001_initial.py +7 -7
  352. edc_protocol_incident/migrations/0001_squashed_0015_auto_20220927_0401.py +13 -13
  353. edc_protocol_incident/migrations/0005_protocolincident_historicalprotocolincident_and_more.py +7 -7
  354. edc_protocol_incident/migrations/0024_alter_actionsrequired_extra_value_and_more.py +625 -0
  355. edc_protocol_incident/migrations/0025_alter_historicalprotocoldeviationviolation_report_datetime_and_more.py +42 -0
  356. edc_protocol_incident/model_mixins/protocol_deviation_violation_model_mixin.py +18 -11
  357. edc_protocol_incident/model_mixins/protocol_incident_model_mixin.py +26 -11
  358. edc_pylabels/actions.py +3 -5
  359. edc_pylabels/auths.py +6 -1
  360. edc_pylabels/migrations/0002_alter_label_options_label_created_and_more.py +3 -7
  361. edc_pylabels/migrations/0005_labelconfiguration_delete_label_and_more.py +3 -3
  362. edc_pylabels/migrations/0013_alter_labelconfiguration_device_created_and_more.py +49 -0
  363. edc_qareports/auths.py +11 -7
  364. edc_qareports/migrations/0001_initial.py +4 -5
  365. edc_qareports/migrations/0005_edcpermissions.py +3 -3
  366. edc_qareports/migrations/0006_qareportlog.py +2 -3
  367. edc_qareports/migrations/0019_alter_edcpermissions_device_created_and_more.py +102 -0
  368. edc_qareports/migrations/0020_alter_note_report_datetime_and_more.py +24 -0
  369. edc_qareports/model_mixins/note_model_mixin.py +7 -4
  370. edc_qareports/model_mixins/on_study_missing_values_model_mixin.py +4 -4
  371. edc_qareports/model_mixins/qa_report_model_mixin.py +2 -3
  372. edc_qareports/models/note.py +4 -4
  373. edc_qareports/models/qa_reports_log.py +2 -3
  374. edc_randomization/admin.py +30 -24
  375. edc_randomization/auths.py +12 -7
  376. edc_randomization/decorators.py +1 -1
  377. edc_randomization/migrations/0001_initial.py +3 -2
  378. edc_randomization/migrations/0002_historicalrandomizationlist.py +3 -2
  379. edc_randomization/migrations/0009_edcpermissions.py +3 -2
  380. edc_randomization/migrations/0014_alter_edcpermissions_device_created_and_more.py +141 -0
  381. edc_randomization/model_mixins.py +9 -9
  382. edc_randomization/randomizer.py +22 -20
  383. edc_randomization/utils.py +19 -18
  384. edc_refusal/auths.py +7 -2
  385. edc_refusal/migrations/0001_initial.py +4 -4
  386. edc_refusal/migrations/0002_historicalsubjectrefusal.py +4 -4
  387. edc_refusal/migrations/0012_alter_historicalsubjectrefusal_comment_and_more.py +122 -0
  388. edc_refusal/migrations/0013_alter_historicalsubjectrefusal_report_datetime_and_more.py +28 -0
  389. edc_refusal/model_mixins.py +4 -4
  390. edc_registration/auths.py +28 -23
  391. edc_registration/migrations/0002_auto_20161127_2226.py +3 -4
  392. edc_registration/migrations/0005_auto_20170111_1809.py +4 -2
  393. edc_registration/migrations/0016_historicalregisteredsubject.py +3 -2
  394. edc_registration/migrations/0017_auto_20190305_0123.py +5 -12
  395. edc_registration/migrations/0033_alter_historicalregisteredsubject_additional_key_and_more.py +302 -0
  396. edc_registration/model_mixins/updates_or_creates_registered_subject_model_mixin.py +15 -7
  397. edc_registration/models/registered_subject.py +28 -27
  398. edc_reportable/age_evaluator.py +4 -2
  399. edc_reportable/formula.py +5 -5
  400. edc_reportable/migrations/0001_initial.py +7 -7
  401. edc_reportable/migrations/0003_referencerangecollection_grade1_and_more.py +3 -3
  402. edc_reportable/migrations/0004_alter_referencerangecollection_grade3_and_more.py +5 -5
  403. edc_reportable/migrations/0006_alter_gradingdata_revision_and_more.py +5 -6
  404. edc_reportable/migrations/0007_alter_gradingdata_age_phrase_and_more.py +509 -0
  405. edc_reportable/models/normal_data.py +4 -5
  406. edc_reportable/models/reference_model_mixins.py +10 -11
  407. edc_reportable/models/reference_range_collection.py +12 -13
  408. edc_reportable/post_migrate_signals.py +1 -1
  409. edc_reportable/utils/convert_units.py +11 -45
  410. edc_reportable/utils/get_normal_data_or_raise.py +2 -2
  411. edc_reportable/utils/get_reference_range_collection.py +2 -3
  412. edc_reportable/utils/load_data.py +4 -4
  413. edc_reportable/utils/update_grading_data.py +5 -5
  414. edc_review_dashboard/auths.py +23 -18
  415. edc_review_dashboard/migrations/0001_initial.py +3 -2
  416. edc_review_dashboard/migrations/0006_alter_edcpermissions_device_created_and_more.py +49 -0
  417. edc_screening/age_evaluator.py +6 -6
  418. edc_screening/auths.py +35 -30
  419. edc_screening/eligibility.py +1 -1
  420. edc_screening/gender_evaluator.py +1 -1
  421. edc_screening/migrations/0001_initial.py +3 -2
  422. edc_screening/migrations/0005_alter_edcpermissions_device_created_and_more.py +49 -0
  423. edc_screening/model_mixins/eligibility_model_mixin.py +3 -6
  424. edc_screening/model_mixins/screening_fields_model_mixin.py +6 -8
  425. edc_screening/model_mixins/screening_methods_model_mixin.py +1 -1
  426. edc_screening/screening_eligibility.py +2 -4
  427. edc_screening/utils.py +9 -9
  428. edc_search/generate_slug.py +26 -0
  429. edc_search/model_mixins.py +10 -22
  430. edc_sites/auths.py +8 -3
  431. edc_sites/migrations/0007_edcpermissions.py +3 -2
  432. edc_sites/migrations/0010_alter_edcpermissions_device_created_and_more.py +69 -0
  433. edc_sites/model_mixins/site_model_mixin.py +2 -2
  434. edc_sites/site.py +5 -5
  435. edc_sites/system_checks.py +1 -1
  436. edc_subject_dashboard/auths.py +27 -22
  437. edc_subject_dashboard/migrations/0001_initial.py +3 -2
  438. edc_subject_dashboard/migrations/0005_alter_edcpermissions_device_created_and_more.py +49 -0
  439. edc_subject_dashboard/requisition_report.py +6 -4
  440. edc_subject_dashboard/requisition_verifier.py +6 -6
  441. edc_subject_dashboard/templatetags/edc_subject_dashboard_extras.py +2 -2
  442. edc_subject_dashboard/view_mixins/subject_visit_view_mixin.py +7 -8
  443. edc_subject_dashboard/view_utils/subject_consent_listboard_button.py +3 -2
  444. edc_subject_dashboard/view_utils/timepoint_status_button.py +2 -2
  445. edc_timepoint/apps.py +0 -21
  446. edc_timepoint/model_mixins.py +22 -20
  447. edc_transfer/model_mixins.py +4 -4
  448. edc_transfer/modeladmin_mixins.py +1 -1
  449. edc_unblinding/auths.py +9 -4
  450. edc_unblinding/migrations/0001_initial.py +13 -13
  451. edc_unblinding/migrations/0014_alter_historicalunblindingrequest_action_identifier_and_more.py +291 -0
  452. edc_unblinding/migrations/0015_alter_historicalunblindingrequest_report_datetime_and_more.py +45 -0
  453. edc_unblinding/models/unblinding_request.py +2 -2
  454. edc_unblinding/models/unblinding_review.py +3 -3
  455. edc_utils/__init__.py +3 -1
  456. edc_utils/age.py +10 -16
  457. edc_utils/show_urls.py +29 -2
  458. edc_visit_schedule/auths.py +6 -1
  459. edc_visit_schedule/migrations/0001_initial.py +3 -3
  460. edc_visit_schedule/migrations/0002_auto_20190305_0123.py +3 -6
  461. edc_visit_schedule/migrations/0003_historicalvisitschedule_visitschedule.py +5 -4
  462. edc_visit_schedule/migrations/0015_historicalonschedule_offschedule_onschedule.py +10 -10
  463. edc_visit_schedule/migrations/0019_alter_historicalonschedule_device_created_and_more.py +229 -0
  464. edc_visit_schedule/migrations/0020_alter_historicalonschedule_onschedule_datetime_and_more.py +65 -0
  465. edc_visit_schedule/model_mixins/off_schedule_model_mixin.py +5 -4
  466. edc_visit_schedule/model_mixins/on_schedule_model_mixin.py +5 -4
  467. edc_visit_schedule/model_mixins/visit_schedule/visit_code_fields_model_mixin.py +1 -1
  468. edc_visit_schedule/models/subject_schedule_history.py +6 -6
  469. edc_visit_schedule/schedule/visit_collection.py +1 -1
  470. edc_visit_schedule/site_visit_schedules.py +2 -2
  471. edc_visit_schedule/subject_schedule.py +5 -4
  472. edc_visit_schedule/view_mixins.py +2 -3
  473. edc_visit_schedule/visit/visit.py +3 -2
  474. edc_visit_tracking/migrations/0004_subjectvisit_subjectvisitmissedreasons_extra_value_and_more.py +13 -13
  475. edc_visit_tracking/migrations/0009_alter_historicalsubjectvisit_comments_and_more.py +450 -0
  476. edc_visit_tracking/migrations/0010_alter_historicalsubjectvisit_report_datetime_and_more.py +68 -0
  477. edc_visit_tracking/model_mixins/base/visit_methods_model_mixin.py +3 -3
  478. edc_visit_tracking/model_mixins/crfs/visit_tracking_crf_model_mixin.py +2 -2
  479. edc_visit_tracking/model_mixins/requisitions/visit_tracking_requisition_model_mixin.py +2 -2
  480. edc_visit_tracking/model_mixins/subject_visit_missed_model_mixin.py +2 -2
  481. edc_visit_tracking/model_mixins/visit_model_mixin/caretaker_fields_mixin.py +2 -3
  482. edc_visit_tracking/model_mixins/visit_model_mixin/previous_visit_model_mixin.py +1 -1
  483. edc_visit_tracking/model_mixins/visit_model_mixin/visit_model_fields_mixin.py +8 -11
  484. edc_visit_tracking/model_mixins/visit_model_mixin/visit_model_mixin.py +1 -1
  485. edc_visit_tracking/models/signals.py +3 -3
  486. edc_visit_tracking/models/subject_visit.py +1 -1
  487. edc_vitals/calculators/bmi.py +7 -5
  488. edc_vitals/utils.py +1 -1
  489. edc_form_label/models.py +0 -0
  490. edc_search/constants.py +0 -1
  491. edc_search/models.py +0 -0
  492. edc_search/search_slug.py +0 -50
  493. edc_search/updater.py +0 -30
  494. edc_search/wsgi.py +0 -7
  495. {clinicedc-2.0.6.dist-info → clinicedc-2.0.8.dist-info}/licenses/LICENSE +0 -0
@@ -1,11 +1,10 @@
1
1
  import csv
2
- import os
3
2
  import uuid
3
+ from pathlib import Path
4
4
 
5
5
  from django.apps import apps as django_apps
6
6
  from django.core.exceptions import ValidationError
7
-
8
- from edc_utils import get_utcnow
7
+ from django.utils import timezone
9
8
 
10
9
  from ..utils import get_export_folder
11
10
  from .file_history_updater import FileHistoryUpdater
@@ -17,11 +16,11 @@ class ModelExporterError(Exception):
17
16
  pass
18
17
 
19
18
 
20
- class ModelExporterInvalidLookup(Exception):
19
+ class ModelExporterInvalidLookup(Exception): # noqa: N818
21
20
  pass
22
21
 
23
22
 
24
- class ModelExporterUnknownField(ValidationError):
23
+ class ModelExporterUnknownField(ValidationError): # noqa: N818
25
24
  pass
26
25
 
27
26
 
@@ -40,14 +39,14 @@ class ModelExporter:
40
39
  value_getter_cls = ValueGetter
41
40
  additional_values_cls = AdditionalValues
42
41
 
43
- export_fields = [
42
+ export_fields = (
44
43
  "export_uuid",
45
44
  "timestamp",
46
45
  "export_datetime",
47
46
  "export_change_type",
48
- ]
49
- required_fields = ["subject_identifier", "report_datetime"]
50
- audit_fields = [
47
+ )
48
+ required_fields = ("subject_identifier", "report_datetime")
49
+ audit_fields = (
51
50
  "hostname_created",
52
51
  "hostname_modified",
53
52
  "created",
@@ -55,7 +54,7 @@ class ModelExporter:
55
54
  "user_created",
56
55
  "user_modified",
57
56
  "revision",
58
- ]
57
+ )
59
58
 
60
59
  def __init__(
61
60
  self,
@@ -103,7 +102,10 @@ class ModelExporter:
103
102
  if f in self.export_fields or f in self.audit_fields or f in self.required_fields:
104
103
  self._field_names.pop(self._field_names.index(f))
105
104
  self._field_names = (
106
- self.export_fields + self.required_fields + self.field_names + self.audit_fields
105
+ *self.export_fields,
106
+ *self.required_fields,
107
+ *self.field_names,
108
+ *self.audit_fields,
107
109
  )
108
110
 
109
111
  @property
@@ -117,13 +119,13 @@ class ModelExporter:
117
119
  self._model_cls = self.queryset.model
118
120
  return self._model_cls
119
121
 
120
- def export(self, queryset=None):
122
+ def export(self, queryset=None) -> Path:
121
123
  """Writes the export file and returns the file name."""
122
124
  self.queryset = queryset or self.queryset
123
- exported_datetime = get_utcnow()
125
+ exported_datetime = timezone.now()
124
126
  filename = self.get_filename(exported_datetime)
125
- path = os.path.join(get_export_folder(), filename)
126
- with open(path, "w") as f:
127
+ path = get_export_folder() / filename
128
+ with path.open("w") as f:
127
129
  csv_writer = csv.DictWriter(
128
130
  f, fieldnames=self.field_names, delimiter=self.delimiter
129
131
  )
@@ -1,9 +1,9 @@
1
1
  from django.apps import apps as django_apps
2
2
  from django.core import serializers
3
3
  from django.core.exceptions import MultipleObjectsReturned, ObjectDoesNotExist
4
+ from django.utils import timezone
4
5
 
5
6
  from edc_constants.constants import NEW
6
- from edc_utils import get_utcnow
7
7
 
8
8
  from ..constants import EXPORTED, INSERT, UPDATE
9
9
 
@@ -24,7 +24,7 @@ class ObjectHistoryCreator(Base):
24
24
  def create(self, model_obj=None, change_type=None, using=None):
25
25
  if not change_type:
26
26
  change_type = self.get_change_type(model_obj=model_obj)
27
- export_datetime = get_utcnow()
27
+ export_datetime = timezone.now()
28
28
  if model_obj._meta.proxy_for_model: # if proxy model, get main model
29
29
  model_obj = model_obj._meta.proxy_for_model.objects.get(id=model_obj.id)
30
30
  obj = self.model_cls.objects.using(using).create(
@@ -1,10 +1,10 @@
1
1
  from django.db import models
2
2
  from django.db.models import Index
3
3
  from django.db.models.deletion import PROTECT
4
+ from django.utils import timezone
4
5
 
5
6
  from edc_model.models import BaseUuidModel
6
7
  from edc_sites.model_mixins import SiteModelMixin
7
- from edc_utils import get_utcnow
8
8
 
9
9
  from .data_request import DataRequest
10
10
 
@@ -12,15 +12,15 @@ from .data_request import DataRequest
12
12
  class DataRequestHistory(SiteModelMixin, BaseUuidModel):
13
13
  data_request = models.ForeignKey(DataRequest, on_delete=PROTECT)
14
14
 
15
- archive_filename = models.CharField(max_length=200, null=True)
15
+ archive_filename = models.CharField(max_length=200, default="")
16
16
 
17
- emailed_to = models.EmailField(null=True)
17
+ emailed_to = models.EmailField(default="")
18
18
 
19
19
  emailed_datetime = models.DateTimeField(null=True)
20
20
 
21
21
  summary = models.TextField(default="")
22
22
 
23
- exported_datetime = models.DateTimeField(default=get_utcnow)
23
+ exported_datetime = models.DateTimeField(default=timezone.now)
24
24
 
25
25
  class Meta:
26
26
  verbose_name = "Data Request History"
edc_export/utils.py CHANGED
@@ -1,10 +1,11 @@
1
1
  from __future__ import annotations
2
2
 
3
- import os
4
3
  import re
5
4
  from collections.abc import Iterable
5
+ from pathlib import Path
6
6
 
7
7
  from django import forms
8
+ from django.conf import settings
8
9
  from django.utils.html import format_html
9
10
 
10
11
  from edc_protocol.research_protocol_config import ResearchProtocolConfig
@@ -13,15 +14,13 @@ from .constants import EXPORT_PII
13
14
  from .exceptions import ExporterExportFolder
14
15
 
15
16
 
16
- def get_export_folder() -> str:
17
- from django.conf import settings
18
-
17
+ def get_export_folder() -> Path:
19
18
  if path := getattr(settings, "EDC_EXPORT_EXPORT_FOLDER", None):
20
- return os.path.expanduser(path)
21
- return os.path.join(settings.MEDIA_ROOT, "data_folder", "export")
19
+ return Path(path).expanduser()
20
+ return Path(settings.MEDIA_ROOT) / "data_folder" / "export"
22
21
 
23
22
 
24
- def get_base_dir() -> str:
23
+ def get_base_dir() -> Path:
25
24
  """Returns the base_dir used by, for example,
26
25
  shutil.make_archive.
27
26
 
@@ -37,20 +36,16 @@ def get_base_dir() -> str:
37
36
  "Invalid base_dir, invalid characters. Using `protocol_lower_name`. "
38
37
  f"Got `{base_dir}`."
39
38
  )
40
- return base_dir
41
-
39
+ return Path(base_dir)
42
40
 
43
- def get_upload_folder() -> str:
44
- from django.conf import settings
45
41
 
42
+ def get_upload_folder() -> Path:
46
43
  if path := getattr(settings, "EDC_EXPORT_UPLOAD_FOLDER", None):
47
- return os.path.expanduser(path)
48
- return os.path.join(settings.MEDIA_ROOT, "data_folder", "upload")
44
+ return Path(path).expanduser()
45
+ return Path(settings.MEDIA_ROOT) / "data_folder" / "upload"
49
46
 
50
47
 
51
48
  def get_export_pii_users() -> list[str]:
52
- from django.conf import settings
53
-
54
49
  return getattr(settings, "EDC_EXPORT_EXPORT_PII_USERS", [])
55
50
 
56
51
 
edc_facility/auths.py CHANGED
@@ -2,6 +2,11 @@ from edc_auth.site_auths import site_auths
2
2
 
3
3
  from .auth_objects import EDC_FACILITY, EDC_FACILITY_SUPER, EDC_FACILITY_VIEW, codenames
4
4
 
5
- site_auths.add_group(*codenames, name=EDC_FACILITY_VIEW, view_only=True)
6
- site_auths.add_group(*codenames, name=EDC_FACILITY, no_delete=True)
7
- site_auths.add_group(*codenames, name=EDC_FACILITY_SUPER)
5
+
6
+ def update_site_auths():
7
+ site_auths.add_group(*codenames, name=EDC_FACILITY_VIEW, view_only=True)
8
+ site_auths.add_group(*codenames, name=EDC_FACILITY, no_delete=True)
9
+ site_auths.add_group(*codenames, name=EDC_FACILITY_SUPER)
10
+
11
+
12
+ update_site_auths()
edc_facility/facility.py CHANGED
@@ -7,17 +7,17 @@ from zoneinfo import ZoneInfo
7
7
 
8
8
  import arrow
9
9
  from arrow import Arrow
10
- from dateutil._common import weekday
11
- from dateutil.relativedelta import relativedelta
10
+ from dateutil.relativedelta import relativedelta, weekday
12
11
  from django.conf import settings
12
+ from django.utils import timezone
13
13
 
14
- from edc_utils import convert_php_dateformat, get_utcnow, to_utc
14
+ from edc_utils import convert_php_dateformat, to_utc
15
15
 
16
16
  from .exceptions import FacilityError
17
17
  from .holidays import Holidays
18
18
 
19
19
  if TYPE_CHECKING:
20
- from django.contrib.sites.models import Site
20
+ pass
21
21
 
22
22
 
23
23
  class Facility:
@@ -34,24 +34,19 @@ class Facility:
34
34
 
35
35
  def __init__(
36
36
  self,
37
- name: str = None,
38
- days: list = None,
39
- slots: list[int] = None,
37
+ name: str | None = None,
38
+ days: list[weekday] | None = None,
39
+ slots: list[int] | None = None,
40
40
  best_effort_available_datetime: datetime | None = None,
41
41
  ):
42
- self.days = []
42
+ self.days = days
43
43
  self.name = name
44
44
  if not name:
45
45
  raise FacilityError(f"Name cannot be None. See {self!r}")
46
46
  self.best_effort_available_datetime = (
47
47
  True if best_effort_available_datetime is None else best_effort_available_datetime
48
48
  )
49
- for day in days:
50
- try:
51
- day.weekday
52
- except AttributeError:
53
- day = weekday(day)
54
- self.days.append(day)
49
+ self.weekdays = [d.weekday for d in self.days]
55
50
  self.slots = slots or [99999 for _ in self.days]
56
51
  self.config = dict(zip([str(d) for d in self.days], self.slots, strict=False))
57
52
  self.holidays = self.holiday_cls()
@@ -72,9 +67,9 @@ class Facility:
72
67
  slots_per_day = 0
73
68
  return slots_per_day
74
69
 
75
- @property
76
- def weekdays(self) -> list[int]:
77
- return [d.weekday for d in self.days]
70
+ # @property
71
+ # def weekdays(self) -> list[int]:
72
+ # return [d.weekday for d in self.days]
78
73
 
79
74
  @staticmethod
80
75
  def open_slot_on(arr) -> Arrow:
@@ -112,7 +107,7 @@ class Facility:
112
107
  span_gt = [arw for arw in span if arw.date() > suggested_arr.date()]
113
108
  arr_span = []
114
109
  max_len = max(len(span_lt), len(span_gt))
115
- for i in range(0, max_len):
110
+ for _ in range(0, max_len):
116
111
  try:
117
112
  item = span_lt.pop()
118
113
  except IndexError:
@@ -135,7 +130,7 @@ class Facility:
135
130
  reverse_delta=None,
136
131
  taken_datetimes=None,
137
132
  schedule_on_holidays=None,
138
- site: Site = None,
133
+ **kwargs, # noqa: ARG002
139
134
  ):
140
135
  """Returns an arrow object for a datetime equal to or
141
136
  close to the suggested datetime.
@@ -153,7 +148,7 @@ class Facility:
153
148
  if suggested_datetime:
154
149
  suggested_arr = arrow.Arrow.fromdatetime(suggested_datetime)
155
150
  else:
156
- suggested_arr = arrow.Arrow.fromdatetime(get_utcnow())
151
+ suggested_arr = arrow.Arrow.fromdatetime(timezone.now())
157
152
  arr_span_range, min_arr, max_arr = self.get_arr_span(
158
153
  suggested_arr,
159
154
  forward_delta,
@@ -185,7 +180,6 @@ class Facility:
185
180
  f"{forward_delta.days} days of {formatted_date}. "
186
181
  f"Facility is {self!r}."
187
182
  )
188
- available_arr = arrow.Arrow.fromdatetime(
183
+ return arrow.Arrow.fromdatetime(
189
184
  datetime.combine(available_arr.date(), suggested_arr.time())
190
185
  )
191
- return available_arr
@@ -9,10 +9,10 @@ from typing import TYPE_CHECKING
9
9
  from django.conf import settings
10
10
  from django.core.exceptions import ObjectDoesNotExist
11
11
  from django.db import transaction
12
+ from django.utils import timezone
12
13
  from tqdm import tqdm
13
14
 
14
15
  from edc_sites.site import sites
15
- from edc_utils import get_utcnow
16
16
 
17
17
  from .exceptions import HolidayFileNotFoundError, HolidayImportError
18
18
  from .utils import get_holiday_model_cls
@@ -30,14 +30,14 @@ def import_holidays(verbose: bool | None = None, test: bool | None = None) -> No
30
30
  if test:
31
31
  import_for_tests(model_cls)
32
32
  else:
33
- path = settings.HOLIDAY_FILE
33
+ path = Path(settings.HOLIDAY_FILE)
34
34
  try:
35
35
  if not Path(path).exists():
36
36
  raise HolidayFileNotFoundError(path)
37
- except TypeError:
37
+ except TypeError as e:
38
38
  raise HolidayImportError(
39
39
  f"Invalid path importing holiday file. See settings.HOLIDAY_FILE. Got {path}."
40
- )
40
+ ) from e
41
41
  if verbose:
42
42
  sys.stdout.write(
43
43
  f"\nImporting holidays from '{path}' into {model_cls._meta.label_lower}\n"
@@ -52,9 +52,9 @@ def import_holidays(verbose: bool | None = None, test: bool | None = None) -> No
52
52
  sys.stdout.write("Done.\n")
53
53
 
54
54
 
55
- def check_for_duplicates_in_file(path) -> list:
55
+ def check_for_duplicates_in_file(path: Path) -> list:
56
56
  """Returns a list of records."""
57
- with open(path) as f:
57
+ with path.open("r") as f:
58
58
  reader = csv.DictReader(f, fieldnames=["local_date", "label", "country"])
59
59
  recs = [(row["local_date"], row["country"]) for row in reader]
60
60
  if len(recs) != len(list(set(recs))):
@@ -62,18 +62,18 @@ def check_for_duplicates_in_file(path) -> list:
62
62
  return recs
63
63
 
64
64
 
65
- def import_file(path: str, recs: list, model_cls: Holiday):
66
- with open(path) as f:
65
+ def import_file(path: Path, recs: list, model_cls: Holiday):
66
+ with path.open("r") as f:
67
67
  reader = csv.DictReader(f, fieldnames=["local_date", "label", "country"])
68
68
  for index, row in tqdm(enumerate(reader), total=len(recs)):
69
69
  if index == 0:
70
70
  continue
71
71
  try:
72
- local_date = datetime.strptime(row["local_date"], "%Y-%m-%d").date()
72
+ local_date = datetime.strptime(row["local_date"], "%Y-%m-%d").date() # noqa: DTZ007
73
73
  except ValueError as e:
74
74
  raise HolidayImportError(
75
75
  f"Invalid format when importing from {path}. Got '{e}'"
76
- )
76
+ ) from e
77
77
  else:
78
78
  try:
79
79
  obj = model_cls.objects.get(country=row["country"], local_date=local_date)
@@ -87,7 +87,7 @@ def import_file(path: str, recs: list, model_cls: Holiday):
87
87
 
88
88
 
89
89
  def import_for_tests(model_cls: type[Holiday]):
90
- year = get_utcnow().year
90
+ year = timezone.now().year
91
91
  country = sites.get_current_country()
92
92
  if not country:
93
93
  raise HolidayImportError(
@@ -112,11 +112,11 @@ def import_for_tests(model_cls: type[Holiday]):
112
112
  if index == 0:
113
113
  continue
114
114
  try:
115
- local_date = datetime.strptime(row[LOCAL_DATE], "%Y-%m-%d").date()
115
+ local_date = datetime.strptime(row[LOCAL_DATE], "%Y-%m-%d").date() # noqa: DTZ007
116
116
  except ValueError as e:
117
117
  raise HolidayImportError(
118
118
  f"Invalid format when importing holidays (test). Got '{e}'"
119
- )
119
+ ) from e
120
120
  else:
121
121
  objs.append(
122
122
  model_cls(country=row[COUNTRY], local_date=local_date, name=row[LABEL])
@@ -17,7 +17,8 @@ from django.db import migrations, models
17
17
  import edc_facility.model_mixins
18
18
  import edc_model_fields.fields.other_charfield
19
19
  import edc_sites.models
20
- import edc_utils.date
20
+ import django.utils.timezone
21
+ import django.utils.timezone
21
22
 
22
23
 
23
24
  class Migration(migrations.Migration):
@@ -46,14 +47,14 @@ class Migration(migrations.Migration):
46
47
  "created",
47
48
  models.DateTimeField(
48
49
  blank=True,
49
- default=django_audit_fields.models.audit_model_mixin.utcnow,
50
+ default=django.utils.timezone.now,
50
51
  ),
51
52
  ),
52
53
  (
53
54
  "modified",
54
55
  models.DateTimeField(
55
56
  blank=True,
56
- default=django_audit_fields.models.audit_model_mixin.utcnow,
57
+ default=django.utils.timezone.now,
57
58
  ),
58
59
  ),
59
60
  (
@@ -105,7 +106,7 @@ class Migration(migrations.Migration):
105
106
  ),
106
107
  (
107
108
  "report_datetime",
108
- models.DateTimeField(default=edc_utils.date.get_utcnow),
109
+ models.DateTimeField(default=django.utils.timezone.now),
109
110
  ),
110
111
  ("name", models.CharField(max_length=25, unique=True)),
111
112
  (
@@ -265,14 +266,14 @@ class Migration(migrations.Migration):
265
266
  "created",
266
267
  models.DateTimeField(
267
268
  blank=True,
268
- default=django_audit_fields.models.audit_model_mixin.utcnow,
269
+ default=django.utils.timezone.now,
269
270
  ),
270
271
  ),
271
272
  (
272
273
  "modified",
273
274
  models.DateTimeField(
274
275
  blank=True,
275
- default=django_audit_fields.models.audit_model_mixin.utcnow,
276
+ default=django.utils.timezone.now,
276
277
  ),
277
278
  ),
278
279
  (
@@ -323,7 +324,7 @@ class Migration(migrations.Migration):
323
324
  ),
324
325
  (
325
326
  "report_datetime",
326
- models.DateTimeField(default=edc_utils.date.get_utcnow),
327
+ models.DateTimeField(default=django.utils.timezone.now),
327
328
  ),
328
329
  ("name", models.CharField(db_index=True, max_length=25)),
329
330
  (
@@ -0,0 +1,139 @@
1
+ # Generated by Django 5.2.6 on 2025-09-17 16:53
2
+
3
+ import edc_model_fields.fields.other_charfield
4
+ from django.db import migrations, models
5
+
6
+
7
+ class Migration(migrations.Migration):
8
+
9
+ dependencies = [
10
+ ("edc_facility", "0015_alter_healthfacility_revision_and_more"),
11
+ ]
12
+
13
+ operations = [
14
+ migrations.AlterField(
15
+ model_name="healthfacility",
16
+ name="device_created",
17
+ field=models.CharField(
18
+ blank=True, default="", max_length=10, verbose_name="Device created"
19
+ ),
20
+ ),
21
+ migrations.AlterField(
22
+ model_name="healthfacility",
23
+ name="device_modified",
24
+ field=models.CharField(
25
+ blank=True, default="", max_length=10, verbose_name="Device modified"
26
+ ),
27
+ ),
28
+ migrations.AlterField(
29
+ model_name="healthfacility",
30
+ name="health_facility_type_other",
31
+ field=edc_model_fields.fields.other_charfield.OtherCharField(
32
+ blank=True,
33
+ default="",
34
+ max_length=35,
35
+ verbose_name="If other, please specify ...",
36
+ ),
37
+ ),
38
+ migrations.AlterField(
39
+ model_name="healthfacility",
40
+ name="locale_created",
41
+ field=models.CharField(
42
+ blank=True,
43
+ default="",
44
+ help_text="Auto-updated by Modeladmin",
45
+ max_length=10,
46
+ verbose_name="Locale created",
47
+ ),
48
+ ),
49
+ migrations.AlterField(
50
+ model_name="healthfacility",
51
+ name="locale_modified",
52
+ field=models.CharField(
53
+ blank=True,
54
+ default="",
55
+ help_text="Auto-updated by Modeladmin",
56
+ max_length=10,
57
+ verbose_name="Locale modified",
58
+ ),
59
+ ),
60
+ migrations.AlterField(
61
+ model_name="healthfacility",
62
+ name="notes",
63
+ field=models.TextField(blank=True, default=""),
64
+ ),
65
+ migrations.AlterField(
66
+ model_name="healthfacilitytypes",
67
+ name="extra_value",
68
+ field=models.CharField(default="", max_length=250),
69
+ ),
70
+ migrations.AlterField(
71
+ model_name="healthfacilitytypes",
72
+ name="field_name",
73
+ field=models.CharField(
74
+ blank=True,
75
+ default="",
76
+ editable=False,
77
+ help_text="Not required",
78
+ max_length=25,
79
+ ),
80
+ ),
81
+ migrations.AlterField(
82
+ model_name="healthfacilitytypes",
83
+ name="plural_name",
84
+ field=models.CharField(
85
+ default="", max_length=250, verbose_name="Plural name"
86
+ ),
87
+ ),
88
+ migrations.AlterField(
89
+ model_name="historicalhealthfacility",
90
+ name="device_created",
91
+ field=models.CharField(
92
+ blank=True, default="", max_length=10, verbose_name="Device created"
93
+ ),
94
+ ),
95
+ migrations.AlterField(
96
+ model_name="historicalhealthfacility",
97
+ name="device_modified",
98
+ field=models.CharField(
99
+ blank=True, default="", max_length=10, verbose_name="Device modified"
100
+ ),
101
+ ),
102
+ migrations.AlterField(
103
+ model_name="historicalhealthfacility",
104
+ name="health_facility_type_other",
105
+ field=edc_model_fields.fields.other_charfield.OtherCharField(
106
+ blank=True,
107
+ default="",
108
+ max_length=35,
109
+ verbose_name="If other, please specify ...",
110
+ ),
111
+ ),
112
+ migrations.AlterField(
113
+ model_name="historicalhealthfacility",
114
+ name="locale_created",
115
+ field=models.CharField(
116
+ blank=True,
117
+ default="",
118
+ help_text="Auto-updated by Modeladmin",
119
+ max_length=10,
120
+ verbose_name="Locale created",
121
+ ),
122
+ ),
123
+ migrations.AlterField(
124
+ model_name="historicalhealthfacility",
125
+ name="locale_modified",
126
+ field=models.CharField(
127
+ blank=True,
128
+ default="",
129
+ help_text="Auto-updated by Modeladmin",
130
+ max_length=10,
131
+ verbose_name="Locale modified",
132
+ ),
133
+ ),
134
+ migrations.AlterField(
135
+ model_name="historicalhealthfacility",
136
+ name="notes",
137
+ field=models.TextField(blank=True, default=""),
138
+ ),
139
+ ]
@@ -0,0 +1,54 @@
1
+ # Generated by Django 5.2.6 on 2025-09-18 00:24
2
+
3
+ import django.utils.timezone
4
+ from django.db import migrations, models
5
+
6
+
7
+ class Migration(migrations.Migration):
8
+
9
+ dependencies = [
10
+ ("edc_facility", "0016_alter_healthfacility_device_created_and_more"),
11
+ ]
12
+
13
+ operations = [
14
+ migrations.AlterField(
15
+ model_name="healthfacility",
16
+ name="gps",
17
+ field=models.CharField(
18
+ blank=True,
19
+ default="",
20
+ help_text="copy and paste directly from google maps",
21
+ max_length=50,
22
+ ),
23
+ ),
24
+ migrations.AlterField(
25
+ model_name="healthfacility",
26
+ name="report_datetime",
27
+ field=models.DateTimeField(default=django.utils.timezone.now),
28
+ ),
29
+ migrations.AlterField(
30
+ model_name="healthfacility",
31
+ name="title",
32
+ field=models.CharField(blank=True, default="", max_length=150),
33
+ ),
34
+ migrations.AlterField(
35
+ model_name="historicalhealthfacility",
36
+ name="gps",
37
+ field=models.CharField(
38
+ blank=True,
39
+ default="",
40
+ help_text="copy and paste directly from google maps",
41
+ max_length=50,
42
+ ),
43
+ ),
44
+ migrations.AlterField(
45
+ model_name="historicalhealthfacility",
46
+ name="report_datetime",
47
+ field=models.DateTimeField(default=django.utils.timezone.now),
48
+ ),
49
+ migrations.AlterField(
50
+ model_name="historicalhealthfacility",
51
+ name="title",
52
+ field=models.CharField(blank=True, default="", max_length=150),
53
+ ),
54
+ ]