endoreg-db 0.8.6.1__py3-none-any.whl → 0.8.8.0__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 endoreg-db might be problematic. Click here for more details.

Files changed (360) hide show
  1. endoreg_db/authz/auth.py +74 -0
  2. endoreg_db/authz/backends.py +168 -0
  3. endoreg_db/authz/management/commands/list_routes.py +18 -0
  4. endoreg_db/authz/middleware.py +83 -0
  5. endoreg_db/authz/permissions.py +127 -0
  6. endoreg_db/authz/policy.py +218 -0
  7. endoreg_db/authz/views_auth.py +66 -0
  8. endoreg_db/config/env.py +13 -8
  9. endoreg_db/data/__init__.py +8 -31
  10. endoreg_db/data/_examples/disease.yaml +55 -0
  11. endoreg_db/data/_examples/disease_classification.yaml +13 -0
  12. endoreg_db/data/_examples/disease_classification_choice.yaml +62 -0
  13. endoreg_db/data/_examples/event.yaml +64 -0
  14. endoreg_db/data/_examples/examination.yaml +72 -0
  15. endoreg_db/data/_examples/finding/anatomy_colon.yaml +128 -0
  16. endoreg_db/data/_examples/finding/colonoscopy.yaml +40 -0
  17. endoreg_db/data/_examples/finding/colonoscopy_bowel_prep.yaml +56 -0
  18. endoreg_db/data/_examples/finding/complication.yaml +16 -0
  19. endoreg_db/data/_examples/finding/data.yaml +105 -0
  20. endoreg_db/data/_examples/finding/examination_setting.yaml +16 -0
  21. endoreg_db/data/_examples/finding/medication_related.yaml +18 -0
  22. endoreg_db/data/_examples/finding/outcome.yaml +12 -0
  23. endoreg_db/data/_examples/finding_classification/colonoscopy_bowel_preparation.yaml +68 -0
  24. endoreg_db/data/_examples/finding_classification/colonoscopy_jnet.yaml +22 -0
  25. endoreg_db/data/_examples/finding_classification/colonoscopy_kudo.yaml +25 -0
  26. endoreg_db/data/_examples/finding_classification/colonoscopy_lesion_circularity.yaml +20 -0
  27. endoreg_db/data/_examples/finding_classification/colonoscopy_lesion_planarity.yaml +24 -0
  28. endoreg_db/data/_examples/finding_classification/colonoscopy_lesion_size.yaml +68 -0
  29. endoreg_db/data/_examples/finding_classification/colonoscopy_lesion_surface.yaml +20 -0
  30. endoreg_db/data/_examples/finding_classification/colonoscopy_location.yaml +80 -0
  31. endoreg_db/data/_examples/finding_classification/colonoscopy_lst.yaml +21 -0
  32. endoreg_db/data/_examples/finding_classification/colonoscopy_nice.yaml +20 -0
  33. endoreg_db/data/_examples/finding_classification/colonoscopy_paris.yaml +26 -0
  34. endoreg_db/data/_examples/finding_classification/colonoscopy_sano.yaml +22 -0
  35. endoreg_db/data/_examples/finding_classification/colonoscopy_summary.yaml +53 -0
  36. endoreg_db/data/_examples/finding_classification/complication_generic.yaml +25 -0
  37. endoreg_db/data/_examples/finding_classification/examination_setting_generic.yaml +40 -0
  38. endoreg_db/data/_examples/finding_classification/histology_colo.yaml +51 -0
  39. endoreg_db/data/_examples/finding_classification/intervention_required.yaml +26 -0
  40. endoreg_db/data/_examples/finding_classification/medication_related.yaml +23 -0
  41. endoreg_db/data/_examples/finding_classification/visualized.yaml +33 -0
  42. endoreg_db/data/_examples/finding_classification_choice/bowel_preparation.yaml +78 -0
  43. endoreg_db/data/_examples/finding_classification_choice/colon_lesion_circularity_default.yaml +32 -0
  44. endoreg_db/data/_examples/finding_classification_choice/colon_lesion_jnet.yaml +15 -0
  45. endoreg_db/data/_examples/finding_classification_choice/colon_lesion_kudo.yaml +23 -0
  46. endoreg_db/data/_examples/finding_classification_choice/colon_lesion_lst.yaml +15 -0
  47. endoreg_db/data/_examples/finding_classification_choice/colon_lesion_nice.yaml +17 -0
  48. endoreg_db/data/_examples/finding_classification_choice/colon_lesion_paris.yaml +57 -0
  49. endoreg_db/data/_examples/finding_classification_choice/colon_lesion_planarity_default.yaml +49 -0
  50. endoreg_db/data/_examples/finding_classification_choice/colon_lesion_sano.yaml +14 -0
  51. endoreg_db/data/_examples/finding_classification_choice/colon_lesion_surface_intact_default.yaml +36 -0
  52. endoreg_db/data/_examples/finding_classification_choice/colonoscopy_location.yaml +229 -0
  53. endoreg_db/data/_examples/finding_classification_choice/colonoscopy_not_complete_reason.yaml +19 -0
  54. endoreg_db/data/_examples/finding_classification_choice/colonoscopy_size.yaml +82 -0
  55. endoreg_db/data/_examples/finding_classification_choice/colonoscopy_summary_worst_finding.yaml +15 -0
  56. endoreg_db/data/_examples/finding_classification_choice/complication_generic_types.yaml +15 -0
  57. endoreg_db/data/_examples/finding_classification_choice/examination_setting_generic_types.yaml +15 -0
  58. endoreg_db/data/_examples/finding_classification_choice/histology.yaml +24 -0
  59. endoreg_db/data/_examples/finding_classification_choice/histology_polyp.yaml +20 -0
  60. endoreg_db/data/_examples/finding_classification_choice/outcome.yaml +19 -0
  61. endoreg_db/data/_examples/finding_classification_choice/yes_no_na.yaml +11 -0
  62. endoreg_db/data/_examples/finding_classification_type/colonoscopy_basic.yaml +48 -0
  63. endoreg_db/data/_examples/finding_intervention/endoscopy.yaml +43 -0
  64. endoreg_db/data/_examples/finding_intervention/endoscopy_colonoscopy.yaml +168 -0
  65. endoreg_db/data/_examples/finding_intervention/endoscopy_egd.yaml +128 -0
  66. endoreg_db/data/_examples/finding_intervention/endoscopy_ercp.yaml +32 -0
  67. endoreg_db/data/_examples/finding_intervention/endoscopy_eus_lower.yaml +9 -0
  68. endoreg_db/data/_examples/finding_intervention/endoscopy_eus_upper.yaml +36 -0
  69. endoreg_db/data/_examples/finding_intervention_type/endoscopy.yaml +15 -0
  70. endoreg_db/data/_examples/finding_type/data.yaml +43 -0
  71. endoreg_db/data/_examples/requirement/age.yaml +26 -0
  72. endoreg_db/data/_examples/requirement/colonoscopy_baseline_austria.yaml +45 -0
  73. endoreg_db/data/_examples/requirement/disease_cardiovascular.yaml +79 -0
  74. endoreg_db/data/_examples/requirement/disease_classification_choice_cardiovascular.yaml +41 -0
  75. endoreg_db/data/_examples/requirement/disease_hepatology.yaml +12 -0
  76. endoreg_db/data/_examples/requirement/disease_misc.yaml +12 -0
  77. endoreg_db/data/_examples/requirement/disease_renal.yaml +96 -0
  78. endoreg_db/data/_examples/requirement/endoscopy_bleeding_risk.yaml +59 -0
  79. endoreg_db/data/_examples/requirement/event_cardiology.yaml +251 -0
  80. endoreg_db/data/_examples/requirement/event_requirements.yaml +145 -0
  81. endoreg_db/data/_examples/requirement/finding_colon_polyp.yaml +50 -0
  82. endoreg_db/data/_examples/requirement/gender.yaml +25 -0
  83. endoreg_db/data/_examples/requirement/lab_value.yaml +441 -0
  84. endoreg_db/data/_examples/requirement/medication.yaml +93 -0
  85. endoreg_db/data/_examples/requirement_operator/age.yaml +13 -0
  86. endoreg_db/data/_examples/requirement_operator/lab_operators.yaml +129 -0
  87. endoreg_db/data/_examples/requirement_operator/model_operators.yaml +96 -0
  88. endoreg_db/data/_examples/requirement_set/01_endoscopy_generic.yaml +48 -0
  89. endoreg_db/data/_examples/requirement_set/colonoscopy_austria_screening.yaml +57 -0
  90. endoreg_db/data/_examples/yaml_examples.xlsx +0 -0
  91. endoreg_db/data/ai_model_meta/default_multilabel_classification.yaml +4 -3
  92. endoreg_db/data/event_classification/data.yaml +4 -0
  93. endoreg_db/data/event_classification_choice/data.yaml +9 -0
  94. endoreg_db/data/finding_classification/colonoscopy_bowel_preparation.yaml +43 -70
  95. endoreg_db/data/finding_classification/colonoscopy_lesion_size.yaml +22 -52
  96. endoreg_db/data/finding_classification/colonoscopy_location.yaml +31 -62
  97. endoreg_db/data/finding_classification/histology_colo.yaml +28 -36
  98. endoreg_db/data/requirement/colon_polyp_intervention.yaml +49 -0
  99. endoreg_db/data/requirement/coloreg_colon_polyp.yaml +49 -0
  100. endoreg_db/data/requirement_set/01_endoscopy_generic.yaml +31 -12
  101. endoreg_db/data/requirement_set/01_laboratory.yaml +13 -0
  102. endoreg_db/data/requirement_set/02_endoscopy_bleeding_risk.yaml +46 -0
  103. endoreg_db/data/requirement_set/90_coloreg.yaml +178 -0
  104. endoreg_db/data/requirement_set/_old_ +109 -0
  105. endoreg_db/data/requirement_set_type/data.yaml +21 -0
  106. endoreg_db/data/setup_config.yaml +4 -4
  107. endoreg_db/data/tag/requirement_set_tags.yaml +21 -0
  108. endoreg_db/exceptions.py +5 -2
  109. endoreg_db/helpers/data_loader.py +1 -1
  110. endoreg_db/management/commands/create_model_meta_from_huggingface.py +21 -10
  111. endoreg_db/management/commands/create_multilabel_model_meta.py +299 -129
  112. endoreg_db/management/commands/import_video.py +9 -10
  113. endoreg_db/management/commands/import_video_with_classification.py +1 -1
  114. endoreg_db/management/commands/init_default_ai_model.py +1 -1
  115. endoreg_db/management/commands/list_routes.py +18 -0
  116. endoreg_db/management/commands/load_center_data.py +12 -12
  117. endoreg_db/management/commands/load_requirement_data.py +60 -31
  118. endoreg_db/management/commands/load_requirement_set_tags.py +95 -0
  119. endoreg_db/management/commands/setup_endoreg_db.py +3 -3
  120. endoreg_db/management/commands/storage_management.py +271 -203
  121. endoreg_db/migrations/0001_initial.py +1799 -1300
  122. endoreg_db/migrations/0002_requirementset_depends_on.py +18 -0
  123. endoreg_db/migrations/_old/0001_initial.py +1857 -0
  124. endoreg_db/migrations/_old/0004_employee_city_employee_post_code_employee_street_and_more.py +68 -0
  125. endoreg_db/migrations/_old/0004_remove_casetemplate_rules_and_more.py +77 -0
  126. endoreg_db/migrations/_old/0005_merge_20251111_1003.py +14 -0
  127. endoreg_db/migrations/_old/0006_sensitivemeta_anonymized_text_and_more.py +68 -0
  128. endoreg_db/migrations/_old/0007_remove_rule_attribute_dtype_remove_rule_rule_type_and_more.py +89 -0
  129. endoreg_db/migrations/_old/0008_remove_event_event_classification_and_more.py +27 -0
  130. endoreg_db/migrations/_old/0009_alter_modelmeta_options_and_more.py +21 -0
  131. endoreg_db/models/__init__.py +78 -123
  132. endoreg_db/models/administration/__init__.py +21 -42
  133. endoreg_db/models/administration/ai/active_model.py +2 -2
  134. endoreg_db/models/administration/ai/ai_model.py +7 -6
  135. endoreg_db/models/administration/case/__init__.py +1 -15
  136. endoreg_db/models/administration/case/case.py +3 -3
  137. endoreg_db/models/administration/case/case_template/__init__.py +2 -14
  138. endoreg_db/models/administration/case/case_template/case_template.py +2 -124
  139. endoreg_db/models/administration/case/case_template/case_template_rule.py +2 -268
  140. endoreg_db/models/administration/case/case_template/case_template_rule_value.py +2 -85
  141. endoreg_db/models/administration/case/case_template/case_template_type.py +2 -25
  142. endoreg_db/models/administration/center/center.py +33 -19
  143. endoreg_db/models/administration/center/center_product.py +12 -9
  144. endoreg_db/models/administration/center/center_resource.py +25 -19
  145. endoreg_db/models/administration/center/center_shift.py +21 -17
  146. endoreg_db/models/administration/center/center_waste.py +16 -8
  147. endoreg_db/models/administration/person/__init__.py +2 -0
  148. endoreg_db/models/administration/person/employee/employee.py +10 -5
  149. endoreg_db/models/administration/person/employee/employee_qualification.py +9 -4
  150. endoreg_db/models/administration/person/employee/employee_type.py +12 -6
  151. endoreg_db/models/administration/person/examiner/examiner.py +13 -11
  152. endoreg_db/models/administration/person/patient/__init__.py +2 -0
  153. endoreg_db/models/administration/person/patient/patient.py +103 -100
  154. endoreg_db/models/administration/person/patient/patient_external_id.py +37 -0
  155. endoreg_db/models/administration/person/person.py +4 -0
  156. endoreg_db/models/administration/person/profession/__init__.py +8 -4
  157. endoreg_db/models/administration/person/user/portal_user_information.py +11 -7
  158. endoreg_db/models/administration/product/product.py +20 -15
  159. endoreg_db/models/administration/product/product_material.py +17 -18
  160. endoreg_db/models/administration/product/product_weight.py +12 -8
  161. endoreg_db/models/administration/product/reference_product.py +23 -55
  162. endoreg_db/models/administration/qualification/qualification.py +7 -3
  163. endoreg_db/models/administration/qualification/qualification_type.py +7 -3
  164. endoreg_db/models/administration/shift/scheduled_days.py +8 -5
  165. endoreg_db/models/administration/shift/shift.py +16 -12
  166. endoreg_db/models/administration/shift/shift_type.py +23 -31
  167. endoreg_db/models/label/__init__.py +7 -8
  168. endoreg_db/models/label/annotation/image_classification.py +10 -9
  169. endoreg_db/models/label/annotation/video_segmentation_annotation.py +8 -5
  170. endoreg_db/models/label/label.py +15 -15
  171. endoreg_db/models/label/label_set.py +19 -6
  172. endoreg_db/models/label/label_type.py +1 -1
  173. endoreg_db/models/label/label_video_segment/_create_from_video.py +5 -8
  174. endoreg_db/models/label/label_video_segment/label_video_segment.py +76 -102
  175. endoreg_db/models/label/video_segmentation_label.py +4 -0
  176. endoreg_db/models/label/video_segmentation_labelset.py +4 -3
  177. endoreg_db/models/media/frame/frame.py +22 -22
  178. endoreg_db/models/media/pdf/raw_pdf.py +110 -182
  179. endoreg_db/models/media/pdf/report_file.py +25 -29
  180. endoreg_db/models/media/pdf/report_reader/report_reader_config.py +30 -46
  181. endoreg_db/models/media/pdf/report_reader/report_reader_flag.py +23 -7
  182. endoreg_db/models/media/video/__init__.py +1 -0
  183. endoreg_db/models/media/video/create_from_file.py +48 -56
  184. endoreg_db/models/media/video/pipe_2.py +8 -9
  185. endoreg_db/models/media/video/video_file.py +150 -108
  186. endoreg_db/models/media/video/video_file_ai.py +288 -74
  187. endoreg_db/models/media/video/video_file_anonymize.py +38 -38
  188. endoreg_db/models/media/video/video_file_frames/__init__.py +3 -1
  189. endoreg_db/models/media/video/video_file_frames/_bulk_create_frames.py +6 -8
  190. endoreg_db/models/media/video/video_file_frames/_create_frame_object.py +7 -9
  191. endoreg_db/models/media/video/video_file_frames/_delete_frames.py +9 -8
  192. endoreg_db/models/media/video/video_file_frames/_extract_frames.py +38 -45
  193. endoreg_db/models/media/video/video_file_frames/_get_frame.py +6 -8
  194. endoreg_db/models/media/video/video_file_frames/_get_frame_number.py +4 -18
  195. endoreg_db/models/media/video/video_file_frames/_get_frame_path.py +4 -3
  196. endoreg_db/models/media/video/video_file_frames/_get_frame_paths.py +7 -6
  197. endoreg_db/models/media/video/video_file_frames/_get_frame_range.py +6 -8
  198. endoreg_db/models/media/video/video_file_frames/_get_frames.py +6 -8
  199. endoreg_db/models/media/video/video_file_frames/_initialize_frames.py +15 -25
  200. endoreg_db/models/media/video/video_file_frames/_manage_frame_range.py +26 -23
  201. endoreg_db/models/media/video/video_file_frames/_mark_frames_extracted_status.py +23 -14
  202. endoreg_db/models/media/video/video_file_io.py +109 -62
  203. endoreg_db/models/media/video/video_file_meta/get_crop_template.py +3 -3
  204. endoreg_db/models/media/video/video_file_meta/get_endo_roi.py +5 -3
  205. endoreg_db/models/media/video/video_file_meta/get_fps.py +37 -34
  206. endoreg_db/models/media/video/video_file_meta/initialize_video_specs.py +19 -25
  207. endoreg_db/models/media/video/video_file_meta/text_meta.py +41 -38
  208. endoreg_db/models/media/video/video_file_meta/video_meta.py +14 -7
  209. endoreg_db/models/media/video/video_file_segments.py +24 -17
  210. endoreg_db/models/media/video/video_metadata.py +19 -35
  211. endoreg_db/models/media/video/video_processing.py +96 -95
  212. endoreg_db/models/medical/contraindication/__init__.py +13 -3
  213. endoreg_db/models/medical/disease.py +22 -16
  214. endoreg_db/models/medical/event.py +31 -18
  215. endoreg_db/models/medical/examination/__init__.py +13 -6
  216. endoreg_db/models/medical/examination/examination.py +17 -18
  217. endoreg_db/models/medical/examination/examination_indication.py +26 -25
  218. endoreg_db/models/medical/examination/examination_time.py +16 -6
  219. endoreg_db/models/medical/examination/examination_time_type.py +9 -6
  220. endoreg_db/models/medical/examination/examination_type.py +3 -4
  221. endoreg_db/models/medical/finding/finding.py +38 -39
  222. endoreg_db/models/medical/finding/finding_classification.py +37 -48
  223. endoreg_db/models/medical/finding/finding_intervention.py +27 -22
  224. endoreg_db/models/medical/finding/finding_type.py +13 -12
  225. endoreg_db/models/medical/hardware/endoscope.py +20 -26
  226. endoreg_db/models/medical/hardware/endoscopy_processor.py +2 -2
  227. endoreg_db/models/medical/laboratory/lab_value.py +62 -91
  228. endoreg_db/models/medical/medication/medication.py +22 -10
  229. endoreg_db/models/medical/medication/medication_indication.py +29 -3
  230. endoreg_db/models/medical/medication/medication_indication_type.py +25 -14
  231. endoreg_db/models/medical/medication/medication_intake_time.py +31 -19
  232. endoreg_db/models/medical/medication/medication_schedule.py +27 -16
  233. endoreg_db/models/medical/organ/__init__.py +15 -12
  234. endoreg_db/models/medical/patient/medication_examples.py +1 -5
  235. endoreg_db/models/medical/patient/patient_disease.py +20 -23
  236. endoreg_db/models/medical/patient/patient_event.py +19 -22
  237. endoreg_db/models/medical/patient/patient_examination.py +48 -54
  238. endoreg_db/models/medical/patient/patient_examination_indication.py +16 -14
  239. endoreg_db/models/medical/patient/patient_finding.py +122 -139
  240. endoreg_db/models/medical/patient/patient_finding_classification.py +44 -49
  241. endoreg_db/models/medical/patient/patient_finding_intervention.py +8 -19
  242. endoreg_db/models/medical/patient/patient_lab_sample.py +28 -23
  243. endoreg_db/models/medical/patient/patient_lab_value.py +82 -89
  244. endoreg_db/models/medical/patient/patient_medication.py +27 -38
  245. endoreg_db/models/medical/patient/patient_medication_schedule.py +28 -36
  246. endoreg_db/models/medical/risk/risk.py +7 -6
  247. endoreg_db/models/medical/risk/risk_type.py +8 -5
  248. endoreg_db/models/metadata/model_meta.py +60 -29
  249. endoreg_db/models/metadata/model_meta_logic.py +125 -18
  250. endoreg_db/models/metadata/pdf_meta.py +19 -24
  251. endoreg_db/models/metadata/sensitive_meta.py +102 -85
  252. endoreg_db/models/metadata/sensitive_meta_logic.py +192 -173
  253. endoreg_db/models/metadata/video_meta.py +51 -31
  254. endoreg_db/models/metadata/video_prediction_logic.py +16 -23
  255. endoreg_db/models/metadata/video_prediction_meta.py +29 -33
  256. endoreg_db/models/other/distribution/date_value_distribution.py +89 -29
  257. endoreg_db/models/other/distribution/multiple_categorical_value_distribution.py +21 -5
  258. endoreg_db/models/other/distribution/numeric_value_distribution.py +114 -53
  259. endoreg_db/models/other/distribution/single_categorical_value_distribution.py +4 -3
  260. endoreg_db/models/other/emission/emission_factor.py +18 -8
  261. endoreg_db/models/other/gender.py +10 -5
  262. endoreg_db/models/other/information_source.py +25 -25
  263. endoreg_db/models/other/material.py +9 -5
  264. endoreg_db/models/other/resource.py +6 -4
  265. endoreg_db/models/other/tag.py +10 -5
  266. endoreg_db/models/other/transport_route.py +13 -8
  267. endoreg_db/models/other/unit.py +10 -6
  268. endoreg_db/models/other/waste.py +6 -5
  269. endoreg_db/models/requirement/requirement.py +580 -272
  270. endoreg_db/models/requirement/requirement_error.py +85 -0
  271. endoreg_db/models/requirement/requirement_evaluation/evaluate_with_dependencies.py +268 -0
  272. endoreg_db/models/requirement/requirement_evaluation/operator_evaluation_models.py +3 -6
  273. endoreg_db/models/requirement/requirement_evaluation/requirement_type_parser.py +90 -64
  274. endoreg_db/models/requirement/requirement_operator.py +36 -33
  275. endoreg_db/models/requirement/requirement_set.py +74 -57
  276. endoreg_db/models/state/__init__.py +4 -4
  277. endoreg_db/models/state/abstract.py +2 -2
  278. endoreg_db/models/state/anonymization.py +12 -0
  279. endoreg_db/models/state/audit_ledger.py +46 -47
  280. endoreg_db/models/state/label_video_segment.py +9 -0
  281. endoreg_db/models/state/raw_pdf.py +40 -46
  282. endoreg_db/models/state/sensitive_meta.py +6 -2
  283. endoreg_db/models/state/video.py +58 -53
  284. endoreg_db/models/upload_job.py +32 -55
  285. endoreg_db/models/utils.py +1 -2
  286. endoreg_db/root_urls.py +21 -2
  287. endoreg_db/serializers/__init__.py +0 -2
  288. endoreg_db/serializers/anonymization.py +18 -10
  289. endoreg_db/serializers/meta/report_meta.py +1 -1
  290. endoreg_db/serializers/meta/sensitive_meta_detail.py +63 -118
  291. endoreg_db/serializers/misc/file_overview.py +11 -99
  292. endoreg_db/serializers/requirements/requirement_sets.py +92 -22
  293. endoreg_db/serializers/video/segmentation.py +2 -1
  294. endoreg_db/serializers/video/video_processing_history.py +20 -5
  295. endoreg_db/services/anonymization.py +75 -73
  296. endoreg_db/services/lookup_service.py +37 -24
  297. endoreg_db/services/pdf_import.py +166 -68
  298. endoreg_db/services/storage_aware_video_processor.py +140 -114
  299. endoreg_db/services/video_import.py +193 -283
  300. endoreg_db/urls/__init__.py +7 -20
  301. endoreg_db/urls/media.py +108 -67
  302. endoreg_db/urls/root_urls.py +29 -0
  303. endoreg_db/utils/__init__.py +15 -5
  304. endoreg_db/utils/ai/multilabel_classification_net.py +116 -20
  305. endoreg_db/utils/case_generator/__init__.py +3 -0
  306. endoreg_db/utils/dataloader.py +88 -16
  307. endoreg_db/utils/defaults/set_default_center.py +32 -0
  308. endoreg_db/utils/names.py +22 -16
  309. endoreg_db/utils/permissions.py +2 -1
  310. endoreg_db/utils/pipelines/process_video_dir.py +1 -1
  311. endoreg_db/utils/requirement_operator_logic/model_evaluators.py +414 -127
  312. endoreg_db/utils/setup_config.py +8 -5
  313. endoreg_db/utils/storage.py +115 -0
  314. endoreg_db/utils/validate_endo_roi.py +8 -2
  315. endoreg_db/utils/video/ffmpeg_wrapper.py +184 -188
  316. endoreg_db/views/__init__.py +0 -10
  317. endoreg_db/views/anonymization/media_management.py +198 -163
  318. endoreg_db/views/anonymization/overview.py +4 -1
  319. endoreg_db/views/anonymization/validate.py +174 -40
  320. endoreg_db/views/media/__init__.py +2 -0
  321. endoreg_db/views/media/pdf_media.py +131 -152
  322. endoreg_db/views/media/sensitive_metadata.py +46 -6
  323. endoreg_db/views/media/video_media.py +89 -82
  324. endoreg_db/views/media/video_segments.py +2 -3
  325. endoreg_db/views/meta/sensitive_meta_detail.py +0 -63
  326. endoreg_db/views/patient/patient.py +5 -4
  327. endoreg_db/views/pdf/pdf_stream.py +20 -21
  328. endoreg_db/views/pdf/reimport.py +11 -32
  329. endoreg_db/views/requirement/evaluate.py +188 -187
  330. endoreg_db/views/requirement/lookup.py +17 -3
  331. endoreg_db/views/requirement/requirement_utils.py +89 -0
  332. endoreg_db/views/video/__init__.py +0 -2
  333. endoreg_db/views/video/correction.py +2 -2
  334. {endoreg_db-0.8.6.1.dist-info → endoreg_db-0.8.8.0.dist-info}/METADATA +7 -3
  335. {endoreg_db-0.8.6.1.dist-info → endoreg_db-0.8.8.0.dist-info}/RECORD +341 -245
  336. endoreg_db/models/administration/permissions/__init__.py +0 -44
  337. endoreg_db/models/media/video/video_file_frames.py +0 -0
  338. endoreg_db/models/metadata/frame_ocr_result.py +0 -0
  339. endoreg_db/models/rule/__init__.py +0 -13
  340. endoreg_db/models/rule/rule.py +0 -27
  341. endoreg_db/models/rule/rule_applicator.py +0 -224
  342. endoreg_db/models/rule/rule_attribute_dtype.py +0 -17
  343. endoreg_db/models/rule/rule_type.py +0 -20
  344. endoreg_db/models/rule/ruleset.py +0 -17
  345. endoreg_db/serializers/video/video_metadata.py +0 -105
  346. endoreg_db/urls/report.py +0 -48
  347. endoreg_db/urls/video.py +0 -61
  348. endoreg_db/utils/case_generator/case_generator.py +0 -159
  349. endoreg_db/utils/case_generator/utils.py +0 -30
  350. endoreg_db/views/report/__init__.py +0 -9
  351. endoreg_db/views/report/report_list.py +0 -112
  352. endoreg_db/views/report/report_with_secure_url.py +0 -28
  353. endoreg_db/views/report/start_examination.py +0 -7
  354. endoreg_db/views.py +0 -0
  355. /endoreg_db/data/{requirement_set → _examples/requirement_set}/endoscopy_bleeding_risk.yaml +0 -0
  356. /endoreg_db/migrations/{0002_add_video_correction_models.py → _old/0002_add_video_correction_models.py} +0 -0
  357. /endoreg_db/migrations/{0003_add_center_display_name.py → _old/0003_add_center_display_name.py} +0 -0
  358. /endoreg_db/{models/media/video/refactor_plan.md → views/pdf/pdf_stream_views.py} +0 -0
  359. {endoreg_db-0.8.6.1.dist-info → endoreg_db-0.8.8.0.dist-info}/WHEEL +0 -0
  360. {endoreg_db-0.8.6.1.dist-info → endoreg_db-0.8.8.0.dist-info}/licenses/LICENSE +0 -0
@@ -1,125 +1,3 @@
1
- from django.db import models
1
+ """Deprecated case template models have been removed."""
2
2
 
3
- class CaseTemplateManager(models.Manager):
4
- def get_by_natural_key(self, name):
5
- return self.get(name=name)
6
-
7
- class CaseTemplate(models.Model):
8
- """
9
- Represents a case template.
10
-
11
- Attributes:
12
- name (str): The unique name of the case template.
13
- template_type (ForeignKey): The type of the case template.
14
- description (str): A description of the case template.
15
- rules: The primary rules associated with the case template.
16
- secondary_rules: Secondary rules associated with the case template.
17
- """
18
- name = models.CharField(max_length=255, unique=True)
19
- template_type = models.ForeignKey("CaseTemplateType", on_delete=models.CASCADE, related_name="case_templates")
20
- description = models.TextField(blank=True, null=True)
21
-
22
- rules = models.ManyToManyField(
23
- "CaseTemplateRule",
24
- )
25
-
26
- secondary_rules = models.ManyToManyField(
27
- "CaseTemplateRule",
28
- related_name="secondary_rules"
29
- )
30
-
31
- objects = CaseTemplateManager()
32
-
33
- def natural_key(self):
34
- """
35
- Returns the natural key for the case template.
36
-
37
- Returns:
38
- tuple: The natural key consisting of the name.
39
- """
40
- return (self.name,)
41
-
42
- def __str__(self):
43
- """
44
- String representation of the case template.
45
-
46
- Returns:
47
- str: The name of the case template.
48
- """
49
- return str(self.name)
50
-
51
- def get_rules(self):
52
- """
53
- Retrieves all primary rules associated with the case template.
54
-
55
- Returns:
56
- A queryset of primary rules.
57
- """
58
- return self.rules.all()
59
-
60
-
61
- def get_secondary_rules(self):
62
- """
63
- Retrieves all secondary rules associated with the case template.
64
-
65
- Returns:
66
- QuerySet: A queryset of secondary rules.
67
- """
68
- rules = self.secondary_rules.all()
69
- return rules
70
-
71
- def _assert_max_one_create_patient_rule(self):
72
- """
73
- Ensures that there is at most one rule with rule_type "create-object" and target_model "Patient".
74
-
75
- Raises:
76
- ValueError: If more than one rule of the specified type exists.
77
- """
78
- create_patient_rules = self.rules.filter(rule_type__name="create-object", target_model__name="Patient")
79
- if len(create_patient_rules) > 1:
80
- raise ValueError(
81
- "There can be at most one rule with the rule_type__name 'create-object' and target_model__name 'Patient'."
82
- )
83
-
84
- # custom save method which runs the _assert_max_one_create_patient_rule method and others
85
- def save(self, *args, **kwargs):
86
- # self._assert_max_one_create_patient_rule() #TODO Fails on first save since many to many can only be used if object has an id
87
- super().save(*args, **kwargs)
88
-
89
- def get_create_patient_rule(self):
90
- """
91
- Retrieves the "create-patient" rule.
92
-
93
- Returns:
94
- CaseTemplateRule: The rule that creates a patient.
95
-
96
- Raises:
97
- ValueError: If multiple such rules exist.
98
- """
99
- from .case_template_rule import CaseTemplateRule
100
- create_patient_rules = self.rules.filter(rule_type__name="create-object", target_model="Patient")
101
- if len(create_patient_rules) > 1:
102
- raise ValueError("There can be at most one rule with the rule_type__name 'create-object' and target_model__name 'Patient'.")
103
- elif len(create_patient_rules) == 0:
104
- create_patient_rules = CaseTemplateRule.objects.get_default_create_patient_rule()
105
- return create_patient_rules[0]
106
-
107
- def get_create_patient_medication_schedule_rule(self):
108
- """
109
- Retrieves the "create-patient_medication_schedule" rule.
110
-
111
- Returns:
112
- CaseTemplateRule: The rule for creating a patient medication schedule.
113
-
114
- Raises:
115
- ValueError: If multiple such rules exist.
116
- """
117
- from .case_template_rule import CaseTemplateRule
118
- create_patient_medication_schedule_rules = self.rules.filter(rule_type__name="create-object", target_model="PatientMedicationSchedule")
119
- if len(create_patient_medication_schedule_rules) > 1:
120
- raise ValueError("There can be at most one rule with the rule_type__name 'create-object' and target_model__name 'PatientMedicationSchedule'.")
121
- elif len(create_patient_medication_schedule_rules) == 0:
122
- from warnings import warn
123
- warn("No create patient medication schedule rule found. Using default create patient medication schedule rule.")
124
- create_patient_medication_schedule_rules = CaseTemplateRule.objects.get_default_create_patient_medication_schedule_rule()
125
- return create_patient_medication_schedule_rules[0]
3
+ __all__: list[str] = []
@@ -1,269 +1,3 @@
1
- from django.db import models
2
-
3
- class CaseTemplateRuleTypeManager(models.Manager):
4
- def get_by_natural_key(self, name):
5
- return self.get(name=name)
6
-
7
- class CaseTemplateRuleType(models.Model):
8
- """
9
- Represents a type of rule for a case template.
10
-
11
- Attributes:
12
- name (str): The name of the rule type.
13
- description (str): A description of the rule type.
14
- """
15
- name = models.CharField(max_length=255)
16
- description = models.TextField(blank=True, null=True)
17
-
18
- objects = CaseTemplateRuleTypeManager()
19
-
20
- def natural_key(self):
21
- return (self.name,)
22
-
23
- def __str__(self):
24
- return str(self.name)
25
-
26
- class CaseTemplateRuleManager(models.Manager):
27
- def get_by_natural_key(self, name):
28
- return self.get(name=name)
29
-
30
- def get_default_create_patient_rule(self):
31
- """Get the default create patient rule."""
32
- return self.get(name="create-patient-default")
33
-
34
- def get_default_create_patient_lab_sample_rules(self):
35
- """Get the default create patient lab sample rules."""
36
- return self.get(name="create-patient_lab_sample-default")
37
-
38
- def get_default_create_patient_medication_schedule_rule(self):
39
- """Get the create patient medication schedule rule."""
40
- r = self.get(name="create-patient_medication_schedule")
41
- assert r, "No create patient medication schedule rule found"
42
- return r
43
-
44
- class CaseTemplateRule(models.Model):
45
- """
46
- A class representing a case template rule.
47
-
48
- Attributes:
49
- name (str): The name of the case template rule.
50
- description (str): A description of the case template rule.
51
- rule_type (CaseTemplateRuleType): The type of the rule.
52
- parent_model (str): The model on which the rule is applied.
53
- target_field (str): The field of the parent model on which the rule is applied.
54
- target_model (str): The model to which the foreign key points (used for foreign key and many-to-many rules).
55
- rule_values (list): A list of string values for the rule.
56
- extra_parameters (dict): A dictionary of extra parameters for the rule.
57
- value_type (CaseTemplateRuleValueType): The type of the rule value.
58
- chained_rules (QuerySet): The chained rules associated with the current rule.
59
- single_categorical_value_distribution (SingleCategoricalValueDistribution): The single categorical value distribution for the rule.
60
- numerical_value_distribution (NumericValueDistribution): The numerical value distribution for the rule.
61
- multiple_categorical_value_distribution (MultipleCategoricalValueDistribution): The multiple categorical value distribution for the rule.
62
- date_value_distribution (DateValueDistribution): The date value distribution for the rule.
63
- objects (CaseTemplateRuleManager): The manager for the CaseTemplateRule model.
64
-
65
- Methods:
66
- natural_key(): Returns the natural key of the rule.
67
- __str__(): Returns a string representation of the rule.
68
- get_rule_type(): Returns the name of the rule type.
69
- get_chained_rules(): Returns all the chained rules associated with the current rule.
70
- get_all_downward_chained_rules(): Returns all the chained rules of the current rule, including indirectly chained rules.
71
- chained_rules_has_self_reference(): Checks if any directly or indirectly chained rules reference this rule, creating a non-terminating loop.
72
- save(*args, **kwargs): Customizes the save method to check for self-references.
73
-
74
- """
75
- name = models.CharField(max_length=255)
76
- description = models.TextField(blank=True, null=True)
77
- rule_type = models.ForeignKey(
78
- "CaseTemplateRuleType", on_delete=models.CASCADE
79
- )
80
- parent_model = models.CharField(max_length=255, blank=True, null=True)
81
- parent_field = models.CharField(max_length=255, blank=True, null=True)
82
- target_field = models.CharField(max_length=255, blank=True, null=True)
83
- target_model = models.CharField(max_length=255, blank=True, null=True)
84
- rule_values = models.JSONField(blank=True, null=True)
85
- extra_parameters = models.JSONField(blank=True, null=True)
86
- value_type = models.ForeignKey("CaseTemplateRuleValueType", on_delete=models.SET_NULL, null=True)
87
- chained_rules = models.ManyToManyField(
88
- "CaseTemplateRule",
89
- related_name="calling_rules"
90
- )
91
- single_categorical_value_distribution = models.ForeignKey(
92
- "SingleCategoricalValueDistribution", on_delete=models.SET_NULL, null=True
93
- )
94
- numerical_value_distribution = models.ForeignKey(
95
- "NumericValueDistribution", on_delete=models.SET_NULL, null=True
96
- )
97
- multiple_categorical_value_distribution = models.ForeignKey(
98
- "MultipleCategoricalValueDistribution", on_delete=models.SET_NULL, null=True
99
- )
100
- date_value_distribution = models.ForeignKey(
101
- "DateValueDistribution", on_delete=models.SET_NULL, null=True
102
- )
103
- objects = CaseTemplateRuleManager()
104
-
105
- def natural_key(self):
106
- """
107
- Returns the natural key of the rule.
108
-
109
- :return: A tuple representing the natural key of the rule.
110
- """
111
- return (self.name,)
112
-
113
- def __str__(self):
114
- """
115
- Returns a string representation of the rule.
116
-
117
- :return: A string representation of the rule.
118
- """
119
- return str(self.name)
120
-
121
- def get_rule_type(self):
122
- """
123
- Returns the name of the rule type.
124
-
125
- :return: The name of the rule type.
126
- """
127
- return self.rule_type.name
128
-
129
- def get_chained_rules(self):
130
- """
131
- Returns all the chained rules associated with the current rule.
132
-
133
- :return: A queryset of all the chained rules associated with the current rule.
134
- """
135
- return self.chained_rules.all()
136
-
137
- def get_distribution(self):
138
- """
139
- Returns the value distribution of the rule.
140
-
141
- :return: The value distribution of the rule.
142
- """
143
- DEBUG = True
144
- if DEBUG:
145
- print("Rule: ", self.name)
146
- print(f"single_categorical_value_distribution: {self.single_categorical_value_distribution}")
147
- print(f"numerical_value_distribution: {self.numerical_value_distribution}")
148
- print(f"multiple_categorical_value_distribution: {self.multiple_categorical_value_distribution}")
149
- print(f"date_value_distribution: {self.date_value_distribution}")
150
-
151
-
152
- if self.single_categorical_value_distribution:
153
- return self.single_categorical_value_distribution
154
- elif self.numerical_value_distribution:
155
- return self.numerical_value_distribution
156
- elif self.multiple_categorical_value_distribution:
157
- return self.multiple_categorical_value_distribution
158
- elif self.date_value_distribution:
159
- return self.date_value_distribution
160
- return None
161
-
162
- def get_all_downward_chained_rules(self):
163
- """
164
- Get all chained rules of the current rule, including indirectly chained rules.
165
-
166
- :return: A set of all chained rules of the current rule.
167
- """
168
- all_chained_rules = set()
169
-
170
- def traverse_chained_rules(rule):
171
- """
172
- Helper function to recursively traverse chained rules.
173
-
174
- :param rule: The current CaseTemplateRule being checked.
175
- :return: None
176
- """
177
- for chained_rule in rule.chained_rules.all():
178
- if chained_rule not in all_chained_rules:
179
- all_chained_rules.add(chained_rule)
180
- traverse_chained_rules(chained_rule)
181
-
182
- # Initialize the traversal starting with the current rule
183
- traverse_chained_rules(self)
184
- return all_chained_rules
185
-
186
- def chained_rules_has_self_reference(self):
187
- """
188
- :noindex:
189
- Check if any directly or indirectly chained rules reference this rule, creating a non-terminating loop.
190
- Return a list containing a tuple (first_rule, self_referencing_rule) for each self-reference.
191
- first_rule is the most upward rule in the chain that references the rule.
192
- self_referencing_rule is the rule that references the current rule itself.
193
-
194
- :return: A list of tuples representing the self-referencing rules.
195
- """
196
- result_list = []
197
-
198
- def traverse_chained_rules(rule, visited_rules):
199
- """
200
- Helper function to recursively traverse chained rules and check for self-references.
201
-
202
- :param rule: The current CaseTemplateRule being checked.
203
- :param visited_rules: A list of tuples representing the path of rules visited so far.
204
- :return: None
205
- """
206
- for chained_rule in rule.chained_rules.all():
207
- if chained_rule == self:
208
- # A self-reference is detected
209
- first_rule = visited_rules[0][0]
210
- self_referencing_rule = visited_rules[-1][1]
211
- result_list.append((first_rule, self_referencing_rule))
212
- elif chained_rule not in [r[1] for r in visited_rules]:
213
- # Continue to check chained rules of the current chained rule
214
- traverse_chained_rules(chained_rule, visited_rules + [(rule, chained_rule)])
215
-
216
- # Initialize the traversal starting with the current rule
217
- traverse_chained_rules(self, [(self, self)])
218
- return result_list
219
-
220
- def get_target_model(self):
221
- """
222
- Returns the target model of the rule.
223
-
224
- :return: The target model of the rule.
225
- """
226
- from django.apps import apps
227
-
228
- if not self.target_model:
229
- return None
230
-
231
- try:
232
- target_model = apps.get_model("endoreg_db", self.target_model)
233
- except LookupError:
234
- raise ValueError(f"Model {self.target_model} not found.")
235
- return target_model
236
-
237
- def get_target_field(self):
238
- """
239
- Returns the target field of the rule.
240
-
241
- :return: The target field of the rule.
242
- """
243
- return self.target_field
244
-
245
- def get_parent_model(self):
246
- """
247
- Returns the parent model of the rule.
248
-
249
- :return: The parent model of the rule.
250
- """
251
- from django.apps import apps
252
-
253
- if not self.parent_model:
254
- return None
255
-
256
- try:
257
- self.parent_model = apps.get_model("endoreg_db", self.parent_model)
258
- except LookupError:
259
- raise ValueError(f"Model {self.parent_model} not found.")
260
- return self.parent_model
261
-
262
- # customize the save method to check for self-references
263
- # def save(self, *args, **kwargs):
264
- # # Check for self-references
265
- # self_referencing_rules = self.chained_rules_has_self_reference()
266
- # if self_referencing_rules:
267
- # raise ValueError(f"Self-references detected: {self_referencing_rules}")
268
- # super().save(*args, **kwargs)
1
+ """Deprecated case template rule models have been removed."""
269
2
 
3
+ __all__: list[str] = []
@@ -1,86 +1,3 @@
1
- from django.db import models
1
+ """Deprecated case template rule value models have been removed."""
2
2
 
3
- class CaseTemplateRuleValueTypeManager(models.Manager):
4
- def get_by_natural_key(self, name):
5
- return self.get(name=name)
6
-
7
- class CaseTemplateRuleValueType(models.Model):
8
- """
9
- A class representing a case template rule value type.
10
-
11
- Attributes:
12
- name (str): The name of the case template rule value type.
13
- distribution_type: One of "single_categorical", "multiple_categorical", "numeric"
14
- description (str): A description of the case template rule value type.
15
- """
16
- DISTRIBUTION_TYPES = [
17
- ("single_categorical", "single_categorical"),
18
- ("multiple_categorical", "multiple_categorical"),
19
- ("numeric", "numeric")
20
- ]
21
- objects = CaseTemplateRuleValueTypeManager()
22
-
23
- name = models.CharField(max_length=255)
24
- description = models.TextField(blank=True, null=True)
25
-
26
- distribution_type = models.CharField(max_length=255, choices=DISTRIBUTION_TYPES)
27
-
28
-
29
- def natural_key(self):
30
- return (self.name,)
31
-
32
- def __str__(self):
33
- return str(self.name)
34
-
35
- class CaseTemplateRuleValueManager(models.Manager):
36
- def get_by_natural_key(self, name):
37
- return self.get(name=name)
38
-
39
- class CaseTemplateRuleValue(models.Model):
40
- """
41
- Represents a case template rule value.
42
-
43
- Attributes:
44
- name (str): The name of the rule value.
45
- description (str): A description of the rule value.
46
- fk_value (str): Foreign key value stored as a string.
47
- numeric_value (float): Numeric value for the rule.
48
- text_value (str): Text value for the rule.
49
- """
50
- objects = CaseTemplateRuleValueManager()
51
-
52
- name = models.CharField(max_length=255)
53
- description = models.TextField(blank=True, null=True)
54
-
55
- fk_value = models.CharField(max_length=255, null=True, blank=True)
56
- numeric_value = models.FloatField(null=True, blank=True)
57
- text_value = models.CharField(max_length=255, null=True, blank=True)
58
-
59
- def natural_key(self):
60
- """
61
- Returns the natural key for the object.
62
- """
63
- return (self.name,)
64
-
65
- def __str__(self):
66
- """
67
- String representation of the object.
68
- """
69
- return str(self.name)
70
-
71
- def get_value(self):
72
- """
73
- Retrieves the value based on priority:
74
- - fk_value > numeric_value > text_value > None.
75
-
76
- Returns:
77
- str | float | None: The value based on the type hierarchy.
78
- """
79
- if self.fk_value:
80
- return self.fk_value
81
- elif self.numeric_value:
82
- return self.numeric_value
83
- elif self.text_value:
84
- return self.text_value
85
- else:
86
- return None
3
+ __all__: list[str] = []
@@ -1,26 +1,3 @@
1
- from django.db import models
1
+ """Deprecated case template type model has been removed."""
2
2
 
3
-
4
- class CaseTemplateTypeManager(models.Manager):
5
- def get_by_natural_key(self, name):
6
- return self.get(name=name)
7
-
8
- class CaseTemplateType(models.Model):
9
- """
10
- A class representing a case template type.
11
-
12
- Attributes:
13
- name (str): The name of the case template type.
14
- description (str): A description of the case template type.
15
-
16
- """
17
- name = models.CharField(max_length=255)
18
- description = models.TextField(blank=True, null=True)
19
-
20
- objects = CaseTemplateTypeManager()
21
-
22
- def natural_key(self):
23
- return (self.name,)
24
-
25
- def __str__(self):
26
- return str(self.name)
3
+ __all__: list[str] = []
@@ -1,13 +1,14 @@
1
+ from typing import TYPE_CHECKING, cast
2
+
1
3
  from django.db import models
2
- from typing import TYPE_CHECKING
3
4
 
4
5
  if TYPE_CHECKING:
5
- from ...medical import Endoscope, EndoscopyProcessor
6
- from ...administration import (
7
- CenterProduct,
8
- CenterWaste, CenterResource
9
- )
6
+ from ...administration import CenterProduct, CenterResource, CenterWaste
10
7
  from ...media import AnonymExaminationReport, AnonymHistologyReport
8
+ from ...medical import Endoscope, EndoscopyProcessor
9
+ from ..person.names.first_name import FirstName
10
+ from ..person.names.last_name import LastName
11
+
11
12
 
12
13
  class CenterManager(models.Manager):
13
14
  def get_by_natural_key(self, name) -> "Center":
@@ -16,8 +17,6 @@ class CenterManager(models.Manager):
16
17
 
17
18
  class Center(models.Model):
18
19
  objects = CenterManager()
19
-
20
- # import_id = models.IntegerField(primary_key=True)
21
20
  name = models.CharField(max_length=255)
22
21
  display_name = models.CharField(max_length=255, blank=True, default="")
23
22
 
@@ -28,16 +27,31 @@ class Center(models.Model):
28
27
  last_names = models.ManyToManyField("LastName", related_name="centers")
29
28
 
30
29
  if TYPE_CHECKING:
31
- # first_names: RelatedManager["FirstName"]
32
- # last_names: RelatedManager["LastName"]
33
- center_products: models.QuerySet["CenterProduct"]
34
- center_resources: models.QuerySet["CenterResource"]
35
- center_wastes: models.QuerySet["CenterWaste"]
36
- endoscopy_processors: models.QuerySet["EndoscopyProcessor"]
37
- endoscopes: models.QuerySet["Endoscope"]
38
- anonymexaminationreport_set: models.QuerySet["AnonymExaminationReport"]
39
- anonymhistologyreport_set: models.QuerySet["AnonymHistologyReport"]
40
-
30
+ from django.db.models.manager import RelatedManager
31
+
32
+ first_names = cast(RelatedManager[FirstName], first_names)
33
+ last_names = cast(RelatedManager[LastName], last_names)
34
+
35
+ @property
36
+ def center_products(self) -> RelatedManager[CenterProduct]: ...
37
+
38
+ @property
39
+ def center_resources(self) -> RelatedManager[CenterResource]: ...
40
+
41
+ @property
42
+ def center_wastes(self) -> RelatedManager[CenterWaste]: ...
43
+
44
+ @property
45
+ def endoscopy_processors(self) -> RelatedManager[EndoscopyProcessor]: ...
46
+
47
+ @property
48
+ def endoscopes(self) -> RelatedManager[Endoscope]: ...
49
+
50
+ @property
51
+ def anonymexaminationreport_set(self) -> RelatedManager[AnonymExaminationReport]: ...
52
+
53
+ @property
54
+ def anonymhistologyreport_set(self) -> RelatedManager[AnonymHistologyReport]: ...
41
55
 
42
56
  @classmethod
43
57
  def get_by_name(cls, name):
@@ -52,7 +66,7 @@ class Center(models.Model):
52
66
  super().save(*args, **kwargs)
53
67
 
54
68
  def __str__(self) -> str:
55
- return str(object=self.display_name or self.name)
69
+ return str(self.display_name or self.name)
56
70
 
57
71
  def get_first_names(self):
58
72
  return self.first_names.all()
@@ -1,8 +1,9 @@
1
- from django.db import models
2
1
  from typing import TYPE_CHECKING
3
2
 
3
+ from django.db import models
4
+
4
5
  if TYPE_CHECKING:
5
- from ..product import Product, ProductGroup
6
+ from ..product import Product
6
7
  from .center import Center
7
8
 
8
9
 
@@ -15,10 +16,11 @@ class CenterProduct(models.Model):
15
16
  date_used (date): The date the product was used.
16
17
  center (Center): The center where the product was used.
17
18
  """
19
+
18
20
  product = models.ForeignKey(
19
21
  "Product",
20
22
  on_delete=models.CASCADE,
21
- related_name="center_products" # Changed related_name for clarity
23
+ related_name="center_products", # Changed related_name for clarity
22
24
  )
23
25
  date_used = models.DateField()
24
26
  center = models.ForeignKey(
@@ -28,25 +30,26 @@ class CenterProduct(models.Model):
28
30
  )
29
31
 
30
32
  if TYPE_CHECKING:
31
- product: "Product"
32
- center: "Center"
33
+ product: models.ForeignKey["Product"]
34
+ center: models.ForeignKey["Center"]
33
35
 
34
36
  class Meta:
35
- ordering = ['center', '-date_used', 'product']
37
+ ordering = ["center", "-date_used", "product"]
36
38
  verbose_name = "Center Product Usage"
37
39
  verbose_name_plural = "Center Product Usages"
38
40
 
39
41
  def __str__(self) -> str:
40
42
  return f"{self.product} - {self.center} - {self.date_used}"
43
+
41
44
  def get_product_name(self) -> str:
42
45
  """Returns the name of the product."""
43
46
  return self.product.name
44
47
 
45
- def get_product_group(self) -> "ProductGroup | None":
48
+ def get_product_group(self):
46
49
  """Returns the ProductGroup associated with this product."""
47
50
  return self.product.product_group
48
51
 
49
- def get_reference_product(self) -> "Product | None":
52
+ def get_reference_product(self):
50
53
  """Returns the reference Product for this product's group."""
51
54
  product_group = self.get_product_group()
52
55
  if product_group:
@@ -55,7 +58,7 @@ class CenterProduct(models.Model):
55
58
 
56
59
  def get_product_weight(self):
57
60
  product = self.product
58
-
61
+
59
62
  return product.get_product_weight()
60
63
 
61
64
  def get_package_weight(self):