diff --git a/.pre-commit-config.yaml b/.pre-commit-config.yaml index ee7d9d6..177df4f 100644 --- a/.pre-commit-config.yaml +++ b/.pre-commit-config.yaml @@ -6,7 +6,7 @@ repos: - hooks: - id: detect-secrets args: [ '--baseline', '.pre-commit/.secrets.baseline' ] - exclude: (config/settings/test.py|/static|.html|local|README.md) + exclude: (config/settings/test.py|/static|.html|local|README.md|.pre-commit/|test_views.py) repo: https://github.com/Yelp/detect-secrets.git rev: v1.4.0 @@ -75,6 +75,6 @@ repos: - hooks: - id: bandit - args: [ --verbose, -ll, --recursive, . ] + args: [ --verbose, -ll, . ] repo: https://github.com/PyCQA/bandit rev: 1.7.7 diff --git a/README.md b/README.md index 10a9e8d..f92083f 100644 --- a/README.md +++ b/README.md @@ -24,8 +24,8 @@ If you want to run _outside_ of Docker you will also need to: If you are on _Windows_ and not Linux (or other *nix) you will also need to have installed: 1. [MSYS](https://www.msys2.org/) or an alternative set of Unix compatible tools that includes `make`. -1. [Microsoft C++ Build Tools](https://visualstudio.microsoft.com/visual-cpp-build-tools/) which are required to install some of the Python [Django](https://www.djangoproject.com/) dependencies. - +1. [Microsoft C++ Build Tools](https://visualstudio.microsoft.com/visual-cpp-build-tools/) which are required to install some of the Python [Django](https://www.djangoproject.com/) dependencies. + ### First time only @@ -37,9 +37,9 @@ pyenv virtualenv registry-api pyenv activate registry-api ``` -Or if you prefer to use [virtualenv](https://virtualenv.pypa.io/en/latest/) directly without pyenv: +Or if you prefer to use [virtualenv](https://virtualenv.pypa.io/en/latest/) directly without pyenv: ``` -# Linux +# Linux $ virtualenv venv $ activate venv diff --git a/checkInCheck.sh b/checkInCheck.sh new file mode 100755 index 0000000..20db580 --- /dev/null +++ b/checkInCheck.sh @@ -0,0 +1,3 @@ +#!/usr/bin/env bash + +make pre-commit && make run && make test diff --git a/config/asgi.py b/config/asgi.py index ddd6aa4..fe96feb 100644 --- a/config/asgi.py +++ b/config/asgi.py @@ -7,6 +7,7 @@ https://docs.djangoproject.com/en/dev/howto/deployment/asgi/ """ + import os import sys from pathlib import Path diff --git a/config/urls.py b/config/urls.py index 50570b3..2d7044c 100644 --- a/config/urls.py +++ b/config/urls.py @@ -33,9 +33,9 @@ TemplateView.as_view( template_name="pages/home.html", extra_context={ - "only_token_auth": True - if "production" in module_type - else False + "only_token_auth": ( + True if "production" in module_type else False + ) }, ), name="home", diff --git a/config/wsgi.py b/config/wsgi.py index 49e770b..97ad3a8 100644 --- a/config/wsgi.py +++ b/config/wsgi.py @@ -13,6 +13,7 @@ framework. """ + import os import sys from pathlib import Path diff --git a/requirements/local.txt b/requirements/local.txt index 7b5518c..9219228 100644 --- a/requirements/local.txt +++ b/requirements/local.txt @@ -22,7 +22,7 @@ flake8==3.8.4 # https://github.com/PyCQA/flake8 flake8-isort==4.0.0 # https://github.com/gforcada/flake8-isort coverage==5.5 # https://github.com/nedbat/coveragepy black==20.8b1 # https://github.com/ambv/black -pylint-django==2.4.4 # https://github.com/PyCQA/pylint-django +pylint-django==2.5.4 # https://github.com/PyCQA/pylint-django pre-commit==2.10.1 # https://github.com/pre-commit/pre-commit isort==4.3.21 # https://github.com/PyCQA/isort diff --git a/tmh_registry/common/utils/functions.py b/tmh_registry/common/utils/functions.py index 01dac95..eb7fca9 100644 --- a/tmh_registry/common/utils/functions.py +++ b/tmh_registry/common/utils/functions.py @@ -3,8 +3,12 @@ def get_text_choice_value_from_label(choices, label): if not label: return None - values = [choice[0] for choice in choices if choice[1].upper() == label.upper()] + values = [ + choice[0] for choice in choices if choice[1].upper() == label.upper() + ] if len(values) == 0: - raise IndexError('Unable to find label "{}" in choices "{}"'.format(label, choices)) + raise IndexError( + 'Unable to find label "{}" in choices "{}"'.format(label, choices) + ) return values[0] diff --git a/tmh_registry/contrib/sites/migrations/0003_set_site_domain_and_name.py b/tmh_registry/contrib/sites/migrations/0003_set_site_domain_and_name.py index 7b46266..c62b932 100644 --- a/tmh_registry/contrib/sites/migrations/0003_set_site_domain_and_name.py +++ b/tmh_registry/contrib/sites/migrations/0003_set_site_domain_and_name.py @@ -3,6 +3,7 @@ http://cookiecutter-django.readthedocs.io/en/latest/faq.html#why-is-there-a-django-contrib-sites-directory-in-cookiecutter-django """ + from django.conf import settings from django.db import migrations diff --git a/tmh_registry/registry/admin.py b/tmh_registry/registry/admin.py index fe32479..2e7f216 100644 --- a/tmh_registry/registry/admin.py +++ b/tmh_registry/registry/admin.py @@ -1,15 +1,16 @@ from django.contrib import admin -from import_export.admin import ExportMixin -from import_export import resources from django.contrib.auth.admin import UserAdmin from django.contrib.auth.models import User - +from import_export import resources +from import_export.admin import ExportMixin from tmh_registry.registry.models import ( + Discharge, Episode, + FollowUp, Hospital, Patient, - PatientHospitalMapping, Discharge, FollowUp, + PatientHospitalMapping, ) @@ -17,10 +18,12 @@ class DischargeAdmin(ExportMixin, admin.ModelAdmin): model = Discharge + @admin.register(FollowUp) class FollowUpAdmin(ExportMixin, admin.ModelAdmin): model = FollowUp + @admin.register(Hospital) class HospitalAdmin(ExportMixin, admin.ModelAdmin): model = Hospital @@ -44,14 +47,17 @@ class EpisodeAdmin(ExportMixin, admin.ModelAdmin): """ To allow CSV export on User model """ + + class UserResource(resources.ModelResource): class Meta: model = User - fields = ('first_name', 'last_name', 'email') + fields = ("first_name", "last_name", "email") + class UserAdmin(ExportMixin, UserAdmin): resource_class = UserResource - pass + admin.site.unregister(User) admin.site.register(User, UserAdmin) diff --git a/tmh_registry/registry/api/serializers.py b/tmh_registry/registry/api/serializers.py index 7e89fc5..a20a659 100644 --- a/tmh_registry/registry/api/serializers.py +++ b/tmh_registry/registry/api/serializers.py @@ -1,6 +1,6 @@ from drf_yasg.utils import swagger_serializer_method from rest_framework.exceptions import ValidationError -from rest_framework.fields import CharField, IntegerField, BooleanField +from rest_framework.fields import BooleanField, CharField, IntegerField from rest_framework.relations import PrimaryKeyRelatedField from rest_framework.serializers import ModelSerializer, SerializerMethodField @@ -150,9 +150,9 @@ def create(self, validated_data): if not validated_data.get("year_of_birth", None): if validated_data["age"]: - validated_data[ - "year_of_birth" - ] = Patient.get_year_of_birth_from_age(validated_data["age"]) + validated_data["year_of_birth"] = ( + Patient.get_year_of_birth_from_age(validated_data["age"]) + ) else: raise ValidationError( { @@ -448,7 +448,7 @@ def create(self, validated_data): ), diathermy_used=validated_data["diathermy_used"], antibiotic_used=validated_data["antibiotic_used"], - antibiotic_type=validated_data.get("antibiotic_type", "") + antibiotic_type=validated_data.get("antibiotic_type", ""), ) except IndexError: raise ValidationError( @@ -473,7 +473,7 @@ class Meta: "aware_of_mesh", "infection", "discharge_duration", - "comments" + "comments", ] @@ -492,7 +492,7 @@ class Meta: "aware_of_mesh", "infection", "discharge_duration", - "comments" + "comments", ] def to_representation(self, instance): @@ -515,7 +515,7 @@ def create(self, validated_data): aware_of_mesh=validated_data["aware_of_mesh"], infection=validated_data.get("infection", ""), discharge_duration=validated_data.get("discharge_duration", None), - comments=validated_data.get("comments", "") + comments=validated_data.get("comments", ""), ) return discharge @@ -539,7 +539,7 @@ class Meta: "infection", "numbness", "further_surgery_need", - "surgery_comments_box" + "surgery_comments_box", ] @@ -551,7 +551,9 @@ class FollowUpWriteSerializer(ModelSerializer): write_only=True, many=True, queryset=MedicalPersonnel.objects.all() ) pain_severity = CharField() - surgery_comments_box = CharField(required=False, allow_blank=True, allow_null=True) + surgery_comments_box = CharField( + required=False, allow_blank=True, allow_null=True + ) further_surgery_need = BooleanField() class Meta: @@ -566,7 +568,7 @@ class Meta: "infection", "numbness", "further_surgery_need", - "surgery_comments_box" + "surgery_comments_box", ] def to_representation(self, instance): @@ -596,17 +598,21 @@ def create(self, validated_data): follow_up = FollowUp.objects.create( episode_id=episode.id, date=validated_data["date"], - pain_severity=get_text_choice_value_from_label( - FollowUp.PainSeverityChoices.choices, pain_severity - ) - if pain_severity - else "", + pain_severity=( + get_text_choice_value_from_label( + FollowUp.PainSeverityChoices.choices, pain_severity + ) + if pain_severity + else "" + ), mesh_awareness=validated_data["mesh_awareness"], seroma=validated_data["seroma"], infection=validated_data["infection"], numbness=validated_data["numbness"], further_surgery_need=validated_data["further_surgery_need"], - surgery_comments_box=validated_data.get("surgery_comments_box", "") + surgery_comments_box=validated_data.get( + "surgery_comments_box", "" + ), ) follow_up.attendees.set(attendees) diff --git a/tmh_registry/registry/api/viewsets.py b/tmh_registry/registry/api/viewsets.py index bf4b498..59faa90 100644 --- a/tmh_registry/registry/api/viewsets.py +++ b/tmh_registry/registry/api/viewsets.py @@ -1,5 +1,6 @@ from django.core.exceptions import ObjectDoesNotExist -from django.db.models import Q, CharField +from django.db.models import CharField, Q +from django.db.models.functions import Cast from django.utils.decorators import method_decorator from django_filters import ( # pylint: disable=E0401 CharFilter, @@ -7,7 +8,6 @@ OrderingFilter, ) from django_filters.rest_framework import FilterSet # pylint: disable=E0401 -from django.db.models.functions import Cast from drf_yasg import openapi from drf_yasg.openapi import IN_QUERY, TYPE_INTEGER, TYPE_STRING, Parameter from drf_yasg.utils import swagger_auto_schema @@ -68,15 +68,26 @@ def filter_hospital(self, queryset, name, value): return queryset def filter_search_term(self, queryset, name, value): - selected_hospital_id_value = self.data.get('hospital_id') + selected_hospital_id_value = self.data.get("hospital_id") if value: - patient_ids = PatientHospitalMapping.objects.annotate( - patient_hospital_id_str=Cast('patient_hospital_id', CharField()) - ).filter( - Q(patient_hospital_id_str__contains=str(value)) & Q(hospital_id=selected_hospital_id_value) - ).values_list("patient_id", flat=True) + patient_ids = ( + PatientHospitalMapping.objects.annotate( + patient_hospital_id_str=Cast( + "patient_hospital_id", CharField() + ) + ) + .filter( + Q(patient_hospital_id_str__contains=str(value)) + & Q(hospital_id=selected_hospital_id_value) + ) + .values_list("patient_id", flat=True) + ) + # pylint: disable=unsupported-binary-operation queryset = queryset.filter( - Q(full_name__icontains=value) | Q(national_id__icontains=value) | Q(id__in=patient_ids) + Q(full_name__icontains=value) + | Q(national_id__iexact=value) + | Q(id__in=patient_ids) + # pylint: enable=unsupported-binary-operation ) return queryset return queryset diff --git a/tmh_registry/registry/migrations/0017_auto_20221029_1535.py b/tmh_registry/registry/migrations/0017_auto_20221029_1535.py index 9ae2b11..e92f9d1 100644 --- a/tmh_registry/registry/migrations/0017_auto_20221029_1535.py +++ b/tmh_registry/registry/migrations/0017_auto_20221029_1535.py @@ -6,13 +6,24 @@ class Migration(migrations.Migration): dependencies = [ - ('registry', '0016_auto_20220222_1415'), + ("registry", "0016_auto_20220222_1415"), ] operations = [ migrations.AlterField( - model_name='episode', - name='episode_type', - field=models.CharField(choices=[('INGUINAL', 'Inguinal Mesh Hernia Repair'), ('INCISIONAL', 'Incisional Mesh Hernia Repair'), ('FEMORAL', 'Femoral Mesh Hernia Repair'), ('UMBILICAL', 'Umbilical/Periumbilicial Mesh Hernia Repair')], max_length=128), + model_name="episode", + name="episode_type", + field=models.CharField( + choices=[ + ("INGUINAL", "Inguinal Mesh Hernia Repair"), + ("INCISIONAL", "Incisional Mesh Hernia Repair"), + ("FEMORAL", "Femoral Mesh Hernia Repair"), + ( + "UMBILICAL", + "Umbilical/Periumbilicial Mesh Hernia Repair", + ), + ], + max_length=128, + ), ), ] diff --git a/tmh_registry/registry/migrations/0018_auto_20221029_1546.py b/tmh_registry/registry/migrations/0018_auto_20221029_1546.py index 115bf8e..824a41a 100644 --- a/tmh_registry/registry/migrations/0018_auto_20221029_1546.py +++ b/tmh_registry/registry/migrations/0018_auto_20221029_1546.py @@ -6,18 +6,33 @@ class Migration(migrations.Migration): dependencies = [ - ('registry', '0017_auto_20221029_1535'), + ("registry", "0017_auto_20221029_1535"), ] operations = [ migrations.AlterField( - model_name='episode', - name='side', - field=models.CharField(choices=[('NA', 'Not Applicable'), ('LEFT', 'Left'), ('RIGHT', 'Right')], max_length=16), + model_name="episode", + name="side", + field=models.CharField( + choices=[ + ("NA", "Not Applicable"), + ("LEFT", "Left"), + ("RIGHT", "Right"), + ], + max_length=16, + ), ), migrations.AlterField( - model_name='episode', - name='type', - field=models.CharField(choices=[('NA', 'Not Applicable'), ('DIRECT', 'Direct'), ('INDIRECT', 'Indirect'), ('PANTALOON', 'Pantaloon')], max_length=16), + model_name="episode", + name="type", + field=models.CharField( + choices=[ + ("NA", "Not Applicable"), + ("DIRECT", "Direct"), + ("INDIRECT", "Indirect"), + ("PANTALOON", "Pantaloon"), + ], + max_length=16, + ), ), ] diff --git a/tmh_registry/registry/migrations/0019_episode_size.py b/tmh_registry/registry/migrations/0019_episode_size.py index d4f2f9a..17cf3b3 100644 --- a/tmh_registry/registry/migrations/0019_episode_size.py +++ b/tmh_registry/registry/migrations/0019_episode_size.py @@ -6,14 +6,25 @@ class Migration(migrations.Migration): dependencies = [ - ('registry', '0018_auto_20221029_1546'), + ("registry", "0018_auto_20221029_1546"), ] operations = [ migrations.AddField( - model_name='episode', - name='size', - field=models.CharField(choices=[('VERY_SMALL', 'Very Small (<1 finger breadth)'), ('SMALL', 'Small (1-2 finger breadths)'), ('MEDIUM', 'Medium (2-3 finger breadths)'), ('LARGE', 'Large (3-4 finger breadths)'), ('VERY_LARGE', 'Very Large (>4 finger breadths)'), ('MASSIVE', 'Massive (extends beyond midpoint of thigh)')], default='SMALL', max_length=16), + model_name="episode", + name="size", + field=models.CharField( + choices=[ + ("VERY_SMALL", "Very Small (<1 finger breadth)"), + ("SMALL", "Small (1-2 finger breadths)"), + ("MEDIUM", "Medium (2-3 finger breadths)"), + ("LARGE", "Large (3-4 finger breadths)"), + ("VERY_LARGE", "Very Large (>4 finger breadths)"), + ("MASSIVE", "Massive (extends beyond midpoint of thigh)"), + ], + default="SMALL", + max_length=16, + ), preserve_default=False, ), ] diff --git a/tmh_registry/registry/migrations/0020_auto_20221029_1710.py b/tmh_registry/registry/migrations/0020_auto_20221029_1710.py index 24c5fdd..6dee626 100644 --- a/tmh_registry/registry/migrations/0020_auto_20221029_1710.py +++ b/tmh_registry/registry/migrations/0020_auto_20221029_1710.py @@ -6,18 +6,18 @@ class Migration(migrations.Migration): dependencies = [ - ('registry', '0019_episode_size'), + ("registry", "0019_episode_size"), ] operations = [ migrations.AddField( - model_name='episode', - name='antibiotic_type', + model_name="episode", + name="antibiotic_type", field=models.TextField(blank=True, null=True), ), migrations.AddField( - model_name='episode', - name='antibiotic_used', + model_name="episode", + name="antibiotic_used", field=models.BooleanField(default=False), preserve_default=False, ), diff --git a/tmh_registry/registry/migrations/0021_auto_20230213_1528.py b/tmh_registry/registry/migrations/0021_auto_20230213_1528.py index 16af232..54f0918 100755 --- a/tmh_registry/registry/migrations/0021_auto_20230213_1528.py +++ b/tmh_registry/registry/migrations/0021_auto_20230213_1528.py @@ -6,18 +6,34 @@ class Migration(migrations.Migration): dependencies = [ - ('registry', '0020_auto_20221029_1710'), + ("registry", "0020_auto_20221029_1710"), ] operations = [ migrations.AlterField( - model_name='episode', - name='complexity', - field=models.CharField(choices=[('SIMPLE', 'Simple'), ('INCARCERATED', 'Irreducible'), ('OBSTRUCTED', 'With bowel obstruction'), ('STRANGULATED', 'Strangulated')], max_length=16), + model_name="episode", + name="complexity", + field=models.CharField( + choices=[ + ("SIMPLE", "Simple"), + ("INCARCERATED", "Irreducible"), + ("OBSTRUCTED", "With bowel obstruction"), + ("STRANGULATED", "Strangulated"), + ], + max_length=16, + ), ), migrations.AlterField( - model_name='episode', - name='mesh_type', - field=models.CharField(choices=[('TNMHP', 'TNMHP Mesh'), ('KCMC', 'KCMC Generic Mesh'), ('COMMERCIAL', 'Commercial Mesh'), ('INTERNATIONAL', 'Hernia Internation Mesh')], max_length=16), + model_name="episode", + name="mesh_type", + field=models.CharField( + choices=[ + ("TNMHP", "TNMHP Mesh"), + ("KCMC", "KCMC Generic Mesh"), + ("COMMERCIAL", "Commercial Mesh"), + ("INTERNATIONAL", "Hernia Internation Mesh"), + ], + max_length=16, + ), ), ] diff --git a/tmh_registry/registry/migrations/0022_auto_20230404_1418.py b/tmh_registry/registry/migrations/0022_auto_20230404_1418.py index 2a94a9d..93799ce 100644 --- a/tmh_registry/registry/migrations/0022_auto_20230404_1418.py +++ b/tmh_registry/registry/migrations/0022_auto_20230404_1418.py @@ -6,18 +6,37 @@ class Migration(migrations.Migration): dependencies = [ - ('registry', '0021_auto_20230213_1528'), + ("registry", "0021_auto_20230213_1528"), ] operations = [ migrations.AlterField( - model_name='episode', - name='antibiotic_type', - field=models.CharField(blank=True, choices=[('START_BEFORE', 'IV at start / before surgery'), ('ONE_DAY_POST_OP_IV', '+24hrs Post Op IV'), ('ONE_DAY_POST_OP_ORAL', '24hrs Post Op Oral'), ('TWO_DAYS_POST_OP_IV', '+48hrs Post Op IV'), ('TWO_DAYS_POST_OP_ORAL', '+48hrs Post Op Oral')], max_length=64, null=True), + model_name="episode", + name="antibiotic_type", + field=models.CharField( + blank=True, + choices=[ + ("START_BEFORE", "IV at start / before surgery"), + ("ONE_DAY_POST_OP_IV", "+24hrs Post Op IV"), + ("ONE_DAY_POST_OP_ORAL", "24hrs Post Op Oral"), + ("TWO_DAYS_POST_OP_IV", "+48hrs Post Op IV"), + ("TWO_DAYS_POST_OP_ORAL", "+48hrs Post Op Oral"), + ], + max_length=64, + null=True, + ), ), migrations.AlterField( - model_name='episode', - name='mesh_type', - field=models.CharField(choices=[('TNMHP', 'TNMHP Mesh'), ('KCMC', 'KCMC Generic Mesh'), ('COMMERCIAL', 'Commercial Mesh'), ('INTERNATIONAL', 'Hernia International Mesh')], max_length=16), + model_name="episode", + name="mesh_type", + field=models.CharField( + choices=[ + ("TNMHP", "TNMHP Mesh"), + ("KCMC", "KCMC Generic Mesh"), + ("COMMERCIAL", "Commercial Mesh"), + ("INTERNATIONAL", "Hernia International Mesh"), + ], + max_length=16, + ), ), ] diff --git a/tmh_registry/registry/migrations/0022_auto_20230525_0641.py b/tmh_registry/registry/migrations/0022_auto_20230525_0641.py index 21ea462..c953f51 100644 --- a/tmh_registry/registry/migrations/0022_auto_20230525_0641.py +++ b/tmh_registry/registry/migrations/0022_auto_20230525_0641.py @@ -6,13 +6,21 @@ class Migration(migrations.Migration): dependencies = [ - ('registry', '0021_auto_20230213_1528'), + ("registry", "0021_auto_20230213_1528"), ] operations = [ migrations.AlterField( - model_name='episode', - name='mesh_type', - field=models.CharField(choices=[('TNMHP', 'TNMHP Mesh'), ('KCMC', 'KCMC Generic Mesh'), ('COMMERCIAL', 'Commercial Mesh'), ('INTERNATIONAL', 'Hernia International Mesh')], max_length=16), + model_name="episode", + name="mesh_type", + field=models.CharField( + choices=[ + ("TNMHP", "TNMHP Mesh"), + ("KCMC", "KCMC Generic Mesh"), + ("COMMERCIAL", "Commercial Mesh"), + ("INTERNATIONAL", "Hernia International Mesh"), + ], + max_length=16, + ), ), ] diff --git a/tmh_registry/registry/migrations/0023_discharge_discharge_duration.py b/tmh_registry/registry/migrations/0023_discharge_discharge_duration.py index f356e24..162218e 100644 --- a/tmh_registry/registry/migrations/0023_discharge_discharge_duration.py +++ b/tmh_registry/registry/migrations/0023_discharge_discharge_duration.py @@ -6,13 +6,13 @@ class Migration(migrations.Migration): dependencies = [ - ('registry', '0022_auto_20230404_1418'), + ("registry", "0022_auto_20230404_1418"), ] operations = [ migrations.AddField( - model_name='discharge', - name='discharge_duration', + model_name="discharge", + name="discharge_duration", field=models.CharField(default=0, max_length=16), preserve_default=False, ), diff --git a/tmh_registry/registry/migrations/0024_auto_20230404_1512.py b/tmh_registry/registry/migrations/0024_auto_20230404_1512.py index 1912d1e..ecb876a 100644 --- a/tmh_registry/registry/migrations/0024_auto_20230404_1512.py +++ b/tmh_registry/registry/migrations/0024_auto_20230404_1512.py @@ -6,13 +6,13 @@ class Migration(migrations.Migration): dependencies = [ - ('registry', '0023_discharge_discharge_duration'), + ("registry", "0023_discharge_discharge_duration"), ] operations = [ migrations.AlterField( - model_name='discharge', - name='discharge_duration', + model_name="discharge", + name="discharge_duration", field=models.CharField(blank=True, max_length=16, null=True), ), ] diff --git a/tmh_registry/registry/migrations/0025_auto_20230404_1536.py b/tmh_registry/registry/migrations/0025_auto_20230404_1536.py index a05ad23..238bbff 100644 --- a/tmh_registry/registry/migrations/0025_auto_20230404_1536.py +++ b/tmh_registry/registry/migrations/0025_auto_20230404_1536.py @@ -6,13 +6,13 @@ class Migration(migrations.Migration): dependencies = [ - ('registry', '0024_auto_20230404_1512'), + ("registry", "0024_auto_20230404_1512"), ] operations = [ migrations.AlterField( - model_name='discharge', - name='infection', + model_name="discharge", + name="infection", field=models.CharField(max_length=64), ), ] diff --git a/tmh_registry/registry/migrations/0026_discharge_comments.py b/tmh_registry/registry/migrations/0026_discharge_comments.py index c35d443..c36b857 100644 --- a/tmh_registry/registry/migrations/0026_discharge_comments.py +++ b/tmh_registry/registry/migrations/0026_discharge_comments.py @@ -6,13 +6,13 @@ class Migration(migrations.Migration): dependencies = [ - ('registry', '0025_auto_20230404_1536'), + ("registry", "0025_auto_20230404_1536"), ] operations = [ migrations.AddField( - model_name='discharge', - name='comments', + model_name="discharge", + name="comments", field=models.TextField(blank=True, null=True), ), ] diff --git a/tmh_registry/registry/migrations/0027_auto_20230404_1555.py b/tmh_registry/registry/migrations/0027_auto_20230404_1555.py index 89e467a..440ba48 100644 --- a/tmh_registry/registry/migrations/0027_auto_20230404_1555.py +++ b/tmh_registry/registry/migrations/0027_auto_20230404_1555.py @@ -6,19 +6,19 @@ class Migration(migrations.Migration): dependencies = [ - ('registry', '0026_discharge_comments'), + ("registry", "0026_discharge_comments"), ] operations = [ migrations.AddField( - model_name='followup', - name='further_surgery_need', + model_name="followup", + name="further_surgery_need", field=models.BooleanField(default=False), preserve_default=False, ), migrations.AddField( - model_name='followup', - name='surgery_comments_box', + model_name="followup", + name="surgery_comments_box", field=models.TextField(blank=True, null=True), ), ] diff --git a/tmh_registry/registry/migrations/0028_auto_20230404_1842.py b/tmh_registry/registry/migrations/0028_auto_20230404_1842.py index db2d794..1d68c41 100644 --- a/tmh_registry/registry/migrations/0028_auto_20230404_1842.py +++ b/tmh_registry/registry/migrations/0028_auto_20230404_1842.py @@ -6,14 +6,16 @@ class Migration(migrations.Migration): dependencies = [ - ('registry', '0027_auto_20230404_1555'), + ("registry", "0027_auto_20230404_1555"), ] operations = [ migrations.AlterField( - model_name='episode', - name='antibiotic_type', - field=models.CharField(default='+24hrs Post Op Oral', max_length=128), + model_name="episode", + name="antibiotic_type", + field=models.CharField( + default="+24hrs Post Op Oral", max_length=128 + ), preserve_default=False, ), ] diff --git a/tmh_registry/registry/migrations/0029_auto_20230411_0759.py b/tmh_registry/registry/migrations/0029_auto_20230411_0759.py index b4cac4a..79b5745 100644 --- a/tmh_registry/registry/migrations/0029_auto_20230411_0759.py +++ b/tmh_registry/registry/migrations/0029_auto_20230411_0759.py @@ -6,13 +6,13 @@ class Migration(migrations.Migration): dependencies = [ - ('registry', '0028_auto_20230404_1842'), + ("registry", "0028_auto_20230404_1842"), ] operations = [ migrations.AlterField( - model_name='episode', - name='antibiotic_type', + model_name="episode", + name="antibiotic_type", field=models.CharField(blank=True, max_length=128, null=True), ), ] diff --git a/tmh_registry/registry/migrations/0030_auto_20230411_0844.py b/tmh_registry/registry/migrations/0030_auto_20230411_0844.py index 50f21c9..b121062 100644 --- a/tmh_registry/registry/migrations/0030_auto_20230411_0844.py +++ b/tmh_registry/registry/migrations/0030_auto_20230411_0844.py @@ -6,13 +6,13 @@ class Migration(migrations.Migration): dependencies = [ - ('registry', '0029_auto_20230411_0759'), + ("registry", "0029_auto_20230411_0759"), ] operations = [ migrations.AlterField( - model_name='discharge', - name='infection', + model_name="discharge", + name="infection", field=models.CharField(blank=True, max_length=64, null=True), ), ] diff --git a/tmh_registry/registry/migrations/0031_auto_20230411_1007.py b/tmh_registry/registry/migrations/0031_auto_20230411_1007.py index b0411be..d1c35f3 100644 --- a/tmh_registry/registry/migrations/0031_auto_20230411_1007.py +++ b/tmh_registry/registry/migrations/0031_auto_20230411_1007.py @@ -6,13 +6,13 @@ class Migration(migrations.Migration): dependencies = [ - ('registry', '0030_auto_20230411_0844'), + ("registry", "0030_auto_20230411_0844"), ] operations = [ migrations.AlterField( - model_name='discharge', - name='discharge_duration', + model_name="discharge", + name="discharge_duration", field=models.PositiveIntegerField(blank=True, null=True), ), ] diff --git a/tmh_registry/registry/migrations/0032_remove_episode_comments.py b/tmh_registry/registry/migrations/0032_remove_episode_comments.py index 124c540..dd4d887 100644 --- a/tmh_registry/registry/migrations/0032_remove_episode_comments.py +++ b/tmh_registry/registry/migrations/0032_remove_episode_comments.py @@ -6,12 +6,12 @@ class Migration(migrations.Migration): dependencies = [ - ('registry', '0031_auto_20230411_1007'), + ("registry", "0031_auto_20230411_1007"), ] operations = [ migrations.RemoveField( - model_name='episode', - name='comments', + model_name="episode", + name="comments", ), ] diff --git a/tmh_registry/registry/migrations/0033_merge_20230525_0733.py b/tmh_registry/registry/migrations/0033_merge_20230525_0733.py index bb96f58..f56f47d 100644 --- a/tmh_registry/registry/migrations/0033_merge_20230525_0733.py +++ b/tmh_registry/registry/migrations/0033_merge_20230525_0733.py @@ -6,9 +6,8 @@ class Migration(migrations.Migration): dependencies = [ - ('registry', '0022_auto_20230525_0641'), - ('registry', '0032_remove_episode_comments'), + ("registry", "0022_auto_20230525_0641"), + ("registry", "0032_remove_episode_comments"), ] - operations = [ - ] + operations = [] diff --git a/tmh_registry/registry/migrations/0034_auto_20230808_0957.py b/tmh_registry/registry/migrations/0034_auto_20230808_0957.py index 1f4b2d6..e636cdf 100644 --- a/tmh_registry/registry/migrations/0034_auto_20230808_0957.py +++ b/tmh_registry/registry/migrations/0034_auto_20230808_0957.py @@ -6,13 +6,25 @@ class Migration(migrations.Migration): dependencies = [ - ('registry', '0033_merge_20230525_0733'), + ("registry", "0033_merge_20230525_0733"), ] operations = [ migrations.AlterField( - model_name='episode', - name='episode_type', - field=models.CharField(choices=[('INGUINAL', 'Inguinal Mesh Hernia Repair'), ('INCISIONAL', 'Incisional Mesh Hernia Repair'), ('FEMORAL', 'Femoral Mesh Hernia Repair'), ('UMBILICAL', 'Umbilical/Periumbilicial Mesh Hernia Repair'), ('EPIGASTRIC', 'Epigastric Hernia')], max_length=128), + model_name="episode", + name="episode_type", + field=models.CharField( + choices=[ + ("INGUINAL", "Inguinal Mesh Hernia Repair"), + ("INCISIONAL", "Incisional Mesh Hernia Repair"), + ("FEMORAL", "Femoral Mesh Hernia Repair"), + ( + "UMBILICAL", + "Umbilical/Periumbilicial Mesh Hernia Repair", + ), + ("EPIGASTRIC", "Epigastric Hernia"), + ], + max_length=128, + ), ), ] diff --git a/tmh_registry/registry/models.py b/tmh_registry/registry/models.py index cdb64f9..3484707 100644 --- a/tmh_registry/registry/models.py +++ b/tmh_registry/registry/models.py @@ -111,12 +111,12 @@ class TypeChoices(TextChoices): PANTALOON = ("PANTALOON", "Pantaloon") class SizeChoices(TextChoices): - VERY_SMALL = ('VERY_SMALL', 'Very Small (<1 finger breadth)') - SMALL = ('SMALL', 'Small (1-2 finger breadths)') - MEDIUM = ('MEDIUM', 'Medium (2-3 finger breadths)') - LARGE = ('LARGE', 'Large (3-4 finger breadths)') - VERY_LARGE = ('VERY_LARGE', 'Very Large (>4 finger breadths)') - MASSIVE = ('MASSIVE', 'Massive (extends beyond midpoint of thigh)') + VERY_SMALL = ("VERY_SMALL", "Very Small (<1 finger breadth)") + SMALL = ("SMALL", "Small (1-2 finger breadths)") + MEDIUM = ("MEDIUM", "Medium (2-3 finger breadths)") + LARGE = ("LARGE", "Large (3-4 finger breadths)") + VERY_LARGE = ("VERY_LARGE", "Very Large (>4 finger breadths)") + MASSIVE = ("MASSIVE", "Massive (extends beyond midpoint of thigh)") class ComplexityChoices(TextChoices): SIMPLE = ("SIMPLE", "Simple") @@ -169,7 +169,9 @@ class Discharge(TimeStampMixin): ) date = DateField() aware_of_mesh = BooleanField() # antibiotics given on discharge - infection = CharField(max_length=64, null=True, blank=True) # Post-operative complications (comma separated values) + infection = CharField( + max_length=64, null=True, blank=True + ) # Post-operative complications (comma separated values) discharge_duration = PositiveIntegerField(null=True, blank=True) comments = TextField(null=True, blank=True) diff --git a/tmh_registry/registry/tests/api/viewsets/episodes/test_post.py b/tmh_registry/registry/tests/api/viewsets/episodes/test_post.py index 11eb9c8..96cea81 100644 --- a/tmh_registry/registry/tests/api/viewsets/episodes/test_post.py +++ b/tmh_registry/registry/tests/api/viewsets/episodes/test_post.py @@ -50,7 +50,7 @@ def get_episode_test_data(self): "anaesthetic_type": Episode.AnaestheticChoices.SPINAL.label, "diathermy_used": True, "antibiotic_used": True, - "antibiotic_type": 'A random antibiotic', + "antibiotic_type": "A random antibiotic", } def setUp(self) -> None: diff --git a/tmh_registry/registry/tests/api/viewsets/test_follow_ups.py b/tmh_registry/registry/tests/api/viewsets/test_follow_ups.py index 8e424cb..37477a3 100644 --- a/tmh_registry/registry/tests/api/viewsets/test_follow_ups.py +++ b/tmh_registry/registry/tests/api/viewsets/test_follow_ups.py @@ -38,7 +38,7 @@ def get_follow_up_data(self): "seroma": True, "infection": False, "numbness": True, - "further_surgery_need": True + "further_surgery_need": True, } def test_successful(self): diff --git a/tmh_registry/registry/tests/api/viewsets/test_patients.py b/tmh_registry/registry/tests/api/viewsets/test_patients.py index 08de4b0..e932ee9 100644 --- a/tmh_registry/registry/tests/api/viewsets/test_patients.py +++ b/tmh_registry/registry/tests/api/viewsets/test_patients.py @@ -1,7 +1,6 @@ import datetime from django.test import TestCase -from parameterized import parameterized from pytest import mark from rest_framework.authtoken.models import Token from rest_framework.status import ( @@ -54,17 +53,17 @@ def setUp(self) -> None: def get_patient_test_data(self): return { "full_name": "Joan MIDDLE Doe", - "national_id": '02668357143554213261', + "national_id": "02668357143554213261", "age": 23, # wrong age "day_of_birth": 3, "month_of_birth": 10, "year_of_birth": 1994, "gender": "Female", - "phone_1": '00234633241', - "phone_2": '00324362141', + "phone_1": "00234633241", + "phone_2": "00324362141", "address": "16 Test Street, Test City, Test Country", "hospital_id": self.hospital.id, - "patient_hospital_id": '001111', + "patient_hospital_id": "001111", } ###################### @@ -312,7 +311,9 @@ def test_create_patients_successful(self): ) self.assertEqual(data["year_of_birth"], response.data["year_of_birth"]) self.assertEqual(data["day_of_birth"], response.data["day_of_birth"]) - self.assertEqual(data["month_of_birth"], response.data["month_of_birth"]) + self.assertEqual( + data["month_of_birth"], response.data["month_of_birth"] + ) self.assertEqual("Female", response.data["gender"]) self.assertEqual(data["phone_1"], response.data["phone_1"]) self.assertEqual(data["phone_2"], response.data["phone_2"]) diff --git a/tmh_registry/registry/urls.py b/tmh_registry/registry/urls.py index 5e35e42..948f081 100644 --- a/tmh_registry/registry/urls.py +++ b/tmh_registry/registry/urls.py @@ -23,4 +23,3 @@ ] # @ todo medical personel required (????) - diff --git a/tmh_registry/users/admin.py b/tmh_registry/users/admin.py index 984341c..47e6401 100644 --- a/tmh_registry/users/admin.py +++ b/tmh_registry/users/admin.py @@ -1,10 +1,9 @@ from django.contrib import admin from import_export.admin import ExportMixin - from tmh_registry.users.models import MedicalPersonnel @admin.register(MedicalPersonnel) -class MedicalPersonnelAdmin(ExportMixin ,admin.ModelAdmin): +class MedicalPersonnelAdmin(ExportMixin, admin.ModelAdmin): model = MedicalPersonnel diff --git a/tmh_registry/users/api/permissions.py b/tmh_registry/users/api/permissions.py index 464ee85..3568509 100644 --- a/tmh_registry/users/api/permissions.py +++ b/tmh_registry/users/api/permissions.py @@ -1,10 +1,9 @@ +import builtins + from rest_framework import permissions from tmh_registry.users.models import MedicalPersonnel -import traceback -import logging - class IsMedicalPersonnel(permissions.BasePermission): message = "MedicalPersonnel instance is required" @@ -14,6 +13,5 @@ def has_permission(self, request, view): return request.user.medical_personnel.user.is_staff except MedicalPersonnel.DoesNotExist: return False - except Exception: + except builtins.Exception: return False - diff --git a/tmh_registry/users/api/serializers.py b/tmh_registry/users/api/serializers.py index 77dc5d9..24b06d3 100644 --- a/tmh_registry/users/api/serializers.py +++ b/tmh_registry/users/api/serializers.py @@ -2,7 +2,11 @@ from django.db import transaction from django.utils.translation import gettext_lazy as _ from rest_framework.fields import CharField -from rest_framework.serializers import ModelSerializer, Serializer, ValidationError +from rest_framework.serializers import ( + ModelSerializer, + Serializer, + ValidationError, +) from ..models import MedicalPersonnel @@ -77,28 +81,35 @@ def update(self, instance, validated_data): # pragma: no cover def create(self, validated_data): # pragma: no cover pass + class ChangePasswordSerializer(Serializer): old_password = CharField(max_length=128, write_only=True, required=True) new_password1 = CharField(max_length=128, write_only=True, required=True) new_password2 = CharField(max_length=128, write_only=True, required=True) def validate_old_password(self, value): - user = self.context['request'].user + user = self.context["request"].user if not user.check_password(value): raise ValidationError( - _('Your old password was entered incorrectly. Please enter it again.') + _( + "Your old password was entered incorrectly. Please enter it again." + ) ) return value def validate(self, data): - if data['new_password1'] != data['new_password2']: - raise ValidationError({'new_password2': _("The two password fields didn't match.")}) - password_validation.validate_password(data['new_password1'], self.context['request'].user) + if data["new_password1"] != data["new_password2"]: + raise ValidationError( + {"new_password2": _("The two password fields didn't match.")} + ) + password_validation.validate_password( + data["new_password1"], self.context["request"].user + ) return data def save(self, **kwargs): - password = self.validated_data['new_password1'] - user = self.context['request'].user + password = self.validated_data["new_password1"] + user = self.context["request"].user user.set_password(password) user.save() return user diff --git a/tmh_registry/users/api/views.py b/tmh_registry/users/api/views.py index dd25376..4abe8ee 100644 --- a/tmh_registry/users/api/views.py +++ b/tmh_registry/users/api/views.py @@ -4,7 +4,7 @@ from django.contrib.auth import authenticate from django.contrib.auth.models import User from drf_yasg.utils import swagger_auto_schema -from rest_framework import status, permissions +from rest_framework import permissions, status from rest_framework.authtoken.models import Token from rest_framework.exceptions import ValidationError from rest_framework.generics import UpdateAPIView @@ -14,8 +14,9 @@ from rest_framework.views import APIView from tmh_registry.users.api.serializers import ( + ChangePasswordSerializer, SignInResponseSerializer, - SignInSerializer, ChangePasswordSerializer + SignInSerializer, ) logger = getLogger(__name__) @@ -118,6 +119,7 @@ def get_serializer_class(self): """ return SignInSerializer + class ChangePasswordView(UpdateAPIView): permission_classes = [permissions.IsAuthenticated] serializer_class = ChangePasswordSerializer @@ -127,12 +129,14 @@ def update(self, request, *args, **kwargs): try: serializer.is_valid(raise_exception=True) except ValidationError as exc: - return Response({"errors": exc.detail}, status=status.HTTP_400_BAD_REQUEST) + return Response( + {"errors": exc.detail}, status=status.HTTP_400_BAD_REQUEST + ) user = serializer.save() # if using drf authtoken, create a new token - if hasattr(user, 'auth_token'): + if hasattr(user, "auth_token"): user.auth_token.delete() - token, created = Token.objects.get_or_create(user=user) + token, _ = Token.objects.get_or_create(user=user) # return new token - return Response({'token': token.key}, status=status.HTTP_200_OK) + return Response({"token": token.key}, status=status.HTTP_200_OK) diff --git a/tmh_registry/users/urls.py b/tmh_registry/users/urls.py index 9c770db..dac9736 100644 --- a/tmh_registry/users/urls.py +++ b/tmh_registry/users/urls.py @@ -1,7 +1,7 @@ from django.urls import include, path from rest_framework.routers import DefaultRouter -from tmh_registry.users.api.views import SignInView, ChangePasswordView +from tmh_registry.users.api.views import ChangePasswordView, SignInView from tmh_registry.users.api.viewsets import MedicalPersonnelViewSet router = DefaultRouter() @@ -10,5 +10,5 @@ urlpatterns = [ path(r"sign-in/", SignInView.as_view()), path(r"", include(router.urls)), - path(r"change-password/", ChangePasswordView.as_view()) + path(r"change-password/", ChangePasswordView.as_view()), ]