Skip to content

Commit

Permalink
Staging release for v24.13.0 (#1993)
Browse files Browse the repository at this point in the history
  • Loading branch information
sainak authored Mar 20, 2024
1 parent 08e56d7 commit 6d68486
Show file tree
Hide file tree
Showing 30 changed files with 1,188 additions and 594 deletions.
6 changes: 3 additions & 3 deletions .github/workflows/docs.yml
Original file line number Diff line number Diff line change
Expand Up @@ -3,12 +3,12 @@ name: Docs
on:
push:
branches:
- master
- develop
paths:
- "docs/**"
pull_request:
branches:
- master
- develop
paths:
- "docs/**"
workflow_dispatch:
Expand Down Expand Up @@ -46,7 +46,7 @@ jobs:
retention-days: 30

deploy-docs:
if: github.repository == 'coronasafe/care' && github.ref == 'refs/heads/master'
if: github.repository == 'coronasafe/care' && github.ref == 'refs/heads/develop'
name: Deploy docs
runs-on: ubuntu-latest
needs: build-docs
Expand Down
6 changes: 4 additions & 2 deletions .github/workflows/linter.yml
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,9 @@ name: Lint Code Base

on:
pull_request:
branches: [master]
branches:
- develop
- staging
merge_group:

jobs:
Expand All @@ -24,7 +26,7 @@ jobs:
- name: Lint Code Base
uses: github/super-linter/slim@v5
env:
DEFAULT_BRANCH: master
DEFAULT_BRANCH: develop
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
VALIDATE_ALL_CODEBASE: false
VALIDATE_PYTHON_BLACK: true
Expand Down
2 changes: 1 addition & 1 deletion .pre-commit-config.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@ repos:
rev: v4.4.0
hooks:
- id: no-commit-to-branch
args: [--branch, master, --branch, production]
args: [--branch, develop, --branch, staging, --branch, production]
- id: check-merge-conflict
- id: check-builtin-literals
- id: mixed-line-ending
Expand Down
2 changes: 1 addition & 1 deletion .vscode/settings.json
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,7 @@
},
"files.trimFinalNewlines": true,
"files.trimTrailingWhitespace": true,
"githubPullRequests.ignoredPullRequestBranches": ["master"],
"githubPullRequests.ignoredPullRequestBranches": ["develop", "staging"],
"python.formatting.blackPath": "${workspaceFolder}/.venv/bin/black",
"python.formatting.provider": "black",
"python.languageServer": "Pylance",
Expand Down
2 changes: 1 addition & 1 deletion CONTRIBUTING.md
Original file line number Diff line number Diff line change
Expand Up @@ -23,7 +23,7 @@ pre-commit install

to run pre-commit on your branch:
```bash
pre-commit run --files $(git diff --name-only master...HEAD)
pre-commit run --files $(git diff --name-only develop...HEAD)
```

#### Using Docker
Expand Down
14 changes: 7 additions & 7 deletions Pipfile
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@ name = "pypi"
[packages]
argon2-cffi = "==23.1.0"
authlib = "==1.2.1"
boto3 = "==1.34.27"
boto3 = "==1.34.65"
celery = "==5.3.6"
django = "==4.2.10"
django-environ = "==0.11.2"
Expand All @@ -23,18 +23,18 @@ django-rest-passwordreset = "==1.3.0"
django-simple-history = "==3.3.0"
djangoql = "==0.17.1"
djangorestframework = "==3.14.0"
djangorestframework-simplejwt = "==5.3.0"
djangorestframework-simplejwt = "==5.3.1"
dry-rest-permissions = "==0.1.10"
drf-nested-routers = "==0.93.4"
drf-spectacular = "==0.26.4"
"fhir.resources" = "==6.5.0"
gunicorn = "==21.2.0"
healthy-django = "==0.1.0"
jsonschema = "==4.20.0"
jwcrypto = "==1.5.1"
jwcrypto = "==1.5.6"
newrelic = "==9.3.0"
pillow = "==10.2.0"
psycopg = "==3.1.14"
psycopg = "==3.1.18"
pycryptodome = "==3.20.0"
pydantic = "==1.10.12" # fix for fhir.resources < 7.0.2
pyjwt = "==2.8.0"
Expand All @@ -48,17 +48,17 @@ redis-om = "==0.2.1"

[dev-packages]
black = "==23.9.1"
boto3-stubs = {extras = ["s3", "boto3"], version = "==1.34.27"}
boto3-stubs = {extras = ["s3", "boto3"], version = "==1.34.65"}
coverage = "==7.4.0"
debugpy = "==1.7.0"
debugpy = "==1.8.1"
django-coverage-plugin = "==3.1.0"
django-debug-toolbar = "==4.2.0"
django-extensions = "==3.2.3"
django-silk = "==5.0.3"
django-stubs = "==4.2.4"
djangorestframework-stubs = "==3.14.2"
factory-boy = "==3.3.0"
flake8 = "==6.1.0"
flake8 = "==7.0.0"
freezegun = "==1.2.2"
ipython = "==8.15.0"
isort = "==5.12.0"
Expand Down
654 changes: 282 additions & 372 deletions Pipfile.lock

Large diffs are not rendered by default.

5 changes: 3 additions & 2 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -36,10 +36,11 @@ You can find the docs at https://care-be-docs.coronasafe.network

### Staging Deployments

Staging instances for testing are automatically deployed on every commit to the `master` branch. The staging instances
are available at:
Dev and staging instances for testing are automatically deployed on every commit to the `develop` and `staging` branches.
The staging instances are available at:

- https://careapi.ohc.network
- https://careapi-staging.ohc.network

### Self hosting

Expand Down
31 changes: 19 additions & 12 deletions care/facility/api/serializers/patient_consultation.py
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,7 @@
Facility,
PatientRegistration,
Prescription,
PrescriptionDosageType,
PrescriptionType,
)
from care.facility.models.asset import AssetLocation
Expand Down Expand Up @@ -151,17 +152,20 @@ class PatientConsultationSerializer(serializers.ModelSerializer):
medico_legal_case = serializers.BooleanField(default=False, required=False)

def get_discharge_prescription(self, consultation):
return Prescription.objects.filter(
consultation=consultation,
prescription_type=PrescriptionType.DISCHARGE.value,
is_prn=False,
).values()
return (
Prescription.objects.filter(
consultation=consultation,
prescription_type=PrescriptionType.DISCHARGE.value,
)
.exclude(dosage_type=PrescriptionDosageType.PRN.value)
.values()
)

def get_discharge_prn_prescription(self, consultation):
return Prescription.objects.filter(
consultation=consultation,
prescription_type=PrescriptionType.DISCHARGE.value,
is_prn=True,
dosage_type=PrescriptionDosageType.PRN.value,
).values()

class Meta:
Expand Down Expand Up @@ -641,17 +645,20 @@ class PatientConsultationDischargeSerializer(serializers.ModelSerializer):
)

def get_discharge_prescription(self, consultation):
return Prescription.objects.filter(
consultation=consultation,
prescription_type=PrescriptionType.DISCHARGE.value,
is_prn=False,
).values()
return (
Prescription.objects.filter(
consultation=consultation,
prescription_type=PrescriptionType.DISCHARGE.value,
)
.exclude(dosage_type=PrescriptionDosageType.PRN.value)
.values()
)

def get_discharge_prn_prescription(self, consultation):
return Prescription.objects.filter(
consultation=consultation,
prescription_type=PrescriptionType.DISCHARGE.value,
is_prn=True,
dosage_type=PrescriptionDosageType.PRN.value,
).values()

class Meta:
Expand Down
121 changes: 76 additions & 45 deletions care/facility/api/serializers/prescription.py
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,12 @@
from django.utils import timezone
from rest_framework import serializers

from care.facility.models import MedibaseMedicine, MedicineAdministration, Prescription
from care.facility.models import (
MedibaseMedicine,
MedicineAdministration,
Prescription,
PrescriptionDosageType,
)
from care.users.api.serializers.user import UserBaseMinimumSerializer


Expand All @@ -19,23 +24,60 @@ class Meta:
)


class MedicineAdministrationSerializer(serializers.ModelSerializer):
id = serializers.UUIDField(source="external_id", read_only=True)

administered_by = UserBaseMinimumSerializer(read_only=True)
archived_by = UserBaseMinimumSerializer(read_only=True)

def validate_administered_date(self, value):
if value > timezone.now():
raise serializers.ValidationError(
"Administered Date cannot be in the future."
)
if self.context["prescription"].created_date > value:
raise serializers.ValidationError(
"Administered Date cannot be before Prescription Date."
)
return value

def validate(self, attrs):
if (
not attrs.get("dosage")
and self.context["prescription"].dosage_type
== PrescriptionDosageType.TITRATED
):
raise serializers.ValidationError(
{"dosage": "Dosage is required for titrated prescriptions."}
)
elif (
self.context["prescription"].dosage_type != PrescriptionDosageType.TITRATED
):
attrs.pop("dosage", None)

return super().validate(attrs)

class Meta:
model = MedicineAdministration
exclude = ("deleted",)
read_only_fields = (
"external_id",
"administered_by",
"archived_by",
"archived_on",
"created_date",
"modified_date",
"prescription",
)


class PrescriptionSerializer(serializers.ModelSerializer):
id = serializers.UUIDField(source="external_id", read_only=True)
prescribed_by = UserBaseMinimumSerializer(read_only=True)
last_administered_on = serializers.SerializerMethodField()
last_administration = MedicineAdministrationSerializer(read_only=True)
medicine_object = MedibaseMedicineSerializer(read_only=True, source="medicine")
medicine = serializers.UUIDField(write_only=True)

def get_last_administered_on(self, obj):
last_administration = (
MedicineAdministration.objects.filter(prescription=obj)
.order_by("-administered_date")
.first()
)
if last_administration:
return last_administration.administered_date
return None

class Meta:
model = Prescription
exclude = (
Expand Down Expand Up @@ -75,47 +117,36 @@ def validate(self, attrs):
}
)

if attrs.get("is_prn"):
if not attrs.get("base_dosage"):
raise serializers.ValidationError(
{"base_dosage": "Base dosage is required."}
)

if attrs.get("dosage_type") == PrescriptionDosageType.PRN:
if not attrs.get("indicator"):
raise serializers.ValidationError(
{"indicator": "Indicator should be set for PRN prescriptions."}
)
attrs.pop("frequency", None)
attrs.pop("days", None)
else:
if not attrs.get("frequency"):
raise serializers.ValidationError(
{"frequency": "Frequency should be set for prescriptions."}
)
attrs.pop("indicator", None)
attrs.pop("max_dosage", None)
attrs.pop("min_hours_between_doses", None)

if attrs.get("dosage_type") == PrescriptionDosageType.TITRATED:
if not attrs.get("target_dosage"):
raise serializers.ValidationError(
{
"target_dosage": "Target dosage should be set for titrated prescriptions."
}
)
else:
attrs.pop("target_dosage", None)

return super().validate(attrs)
# TODO: Ensure that this medicine is not already prescribed to the same patient and is currently active.


class MedicineAdministrationSerializer(serializers.ModelSerializer):
id = serializers.UUIDField(source="external_id", read_only=True)

administered_by = UserBaseMinimumSerializer(read_only=True)
prescription = PrescriptionSerializer(read_only=True)
archived_by = UserBaseMinimumSerializer(read_only=True)

def validate_administered_date(self, value):
if value > timezone.now():
raise serializers.ValidationError(
"Administered Date cannot be in the future."
)
if self.context["prescription"].created_date > value:
raise serializers.ValidationError(
"Administered Date cannot be before Prescription Date."
)
return value

class Meta:
model = MedicineAdministration
exclude = ("deleted",)
read_only_fields = (
"external_id",
"administered_by",
"archived_by",
"archived_on",
"created_date",
"modified_date",
"prescription",
)
Loading

0 comments on commit 6d68486

Please sign in to comment.