mirror of
https://github.com/beak-insights/felicity-lims.git
synced 2025-02-21 07:22:53 +08:00
added result type column
This commit is contained in:
parent
a435790e53
commit
6f6155e6b2
22 changed files with 2489 additions and 200 deletions
|
@ -6,9 +6,27 @@
|
|||
<component name="ChangeListManager">
|
||||
<list default="true" id="9f590b69-f929-45a1-8512-12ed6efbf028" name="Changes" comment="Added Invetory starter">
|
||||
<change beforePath="$PROJECT_DIR$/.idea/workspace.xml" beforeDir="false" afterPath="$PROJECT_DIR$/.idea/workspace.xml" afterDir="false" />
|
||||
<change beforePath="$PROJECT_DIR$/felicity/api/gql/setup/types/setup.py" beforeDir="false" afterPath="$PROJECT_DIR$/felicity/api/gql/setup/types/setup.py" afterDir="false" />
|
||||
<change beforePath="$PROJECT_DIR$/felicity/apps/analysis/conf.py" beforeDir="false" afterPath="$PROJECT_DIR$/felicity/apps/analysis/conf.py" afterDir="false" />
|
||||
<change beforePath="$PROJECT_DIR$/felicity/apps/analysis/models/analysis.py" beforeDir="false" afterPath="$PROJECT_DIR$/felicity/apps/analysis/models/analysis.py" afterDir="false" />
|
||||
<change beforePath="$PROJECT_DIR$/felicity/apps/analysis/models/results.py" beforeDir="false" afterPath="$PROJECT_DIR$/felicity/apps/analysis/models/results.py" afterDir="false" />
|
||||
<change beforePath="$PROJECT_DIR$/felicity/apps/analysis/schemas.py" beforeDir="false" afterPath="$PROJECT_DIR$/felicity/apps/analysis/schemas.py" afterDir="false" />
|
||||
<change beforePath="$PROJECT_DIR$/felicity/apps/setup/models/location.py" beforeDir="false" afterPath="$PROJECT_DIR$/felicity/apps/setup/models/location.py" afterDir="false" />
|
||||
<change beforePath="$PROJECT_DIR$/felicity/apps/setup/models/setup.py" beforeDir="false" afterPath="$PROJECT_DIR$/felicity/apps/setup/models/setup.py" afterDir="false" />
|
||||
<change beforePath="$PROJECT_DIR$/felicity/apps/setup/schemas.py" beforeDir="false" afterPath="$PROJECT_DIR$/felicity/apps/setup/schemas.py" afterDir="false" />
|
||||
<change beforePath="$PROJECT_DIR$/felicity/lims/seeds/data/analyses.json" beforeDir="false" afterPath="$PROJECT_DIR$/felicity/lims/seeds/data/analyses.json" afterDir="false" />
|
||||
<change beforePath="$PROJECT_DIR$/felicity/lims/seeds/data/laboratory.json" beforeDir="false" afterPath="$PROJECT_DIR$/felicity/lims/seeds/data/laboratory.json" afterDir="false" />
|
||||
<change beforePath="$PROJECT_DIR$/felicity/lims/seeds/data/ucuum.json" beforeDir="false" afterPath="$PROJECT_DIR$/felicity/lims/seeds/data/ucuum.json" afterDir="false" />
|
||||
<change beforePath="$PROJECT_DIR$/felicity/lims/seeds/setup_analyses.py" beforeDir="false" afterPath="$PROJECT_DIR$/felicity/lims/seeds/setup_analyses.py" afterDir="false" />
|
||||
<change beforePath="$PROJECT_DIR$/webapp/api.ts" beforeDir="false" afterPath="$PROJECT_DIR$/webapp/api.ts" afterDir="false" />
|
||||
<change beforePath="$PROJECT_DIR$/felicity/migrations/versions/3e36503be66f_init_db.py" beforeDir="false" />
|
||||
<change beforePath="$PROJECT_DIR$/webapp/graphql/operations/analyses.queries.ts" beforeDir="false" afterPath="$PROJECT_DIR$/webapp/graphql/operations/analyses.queries.ts" afterDir="false" />
|
||||
<change beforePath="$PROJECT_DIR$/webapp/graphql/operations/instrument.mutations.ts" beforeDir="false" afterPath="$PROJECT_DIR$/webapp/graphql/operations/instrument.mutations.ts" afterDir="false" />
|
||||
<change beforePath="$PROJECT_DIR$/webapp/graphql/operations/instrument.queries.ts" beforeDir="false" afterPath="$PROJECT_DIR$/webapp/graphql/operations/instrument.queries.ts" afterDir="false" />
|
||||
<change beforePath="$PROJECT_DIR$/webapp/models/setup.ts" beforeDir="false" afterPath="$PROJECT_DIR$/webapp/models/setup.ts" afterDir="false" />
|
||||
<change beforePath="$PROJECT_DIR$/webapp/views/admin/analyses/AnalysesProfiles.vue" beforeDir="false" afterPath="$PROJECT_DIR$/webapp/views/admin/analyses/AnalysesProfiles.vue" afterDir="false" />
|
||||
<change beforePath="$PROJECT_DIR$/webapp/views/admin/analyses/services/ServicesAdmin.vue" beforeDir="false" afterPath="$PROJECT_DIR$/webapp/views/admin/analyses/services/ServicesAdmin.vue" afterDir="false" />
|
||||
<change beforePath="$PROJECT_DIR$/webapp/views/admin/instruments/Units.vue" beforeDir="false" afterPath="$PROJECT_DIR$/webapp/views/admin/instruments/Units.vue" afterDir="false" />
|
||||
<change beforePath="$PROJECT_DIR$/webapp/views/admin/users/Groups.vue" beforeDir="false" afterPath="$PROJECT_DIR$/webapp/views/admin/users/Groups.vue" afterDir="false" />
|
||||
</list>
|
||||
<option name="SHOW_DIALOG" value="false" />
|
||||
<option name="HIGHLIGHT_CONFLICTS" value="true" />
|
||||
|
|
|
@ -93,7 +93,7 @@ class ManufacturerType:
|
|||
class UnitType:
|
||||
uid: str
|
||||
name: str
|
||||
is_si_unit: bool
|
||||
description: str | None
|
||||
#
|
||||
created_by_uid: str | None
|
||||
created_by: Optional["UserType"]
|
||||
|
|
|
@ -50,3 +50,12 @@ class Priorities(object):
|
|||
|
||||
|
||||
priorities = Priorities()
|
||||
|
||||
|
||||
class ResultType:
|
||||
NUMERIC = "numeric" # strict numeric
|
||||
SHORT_TEXT = "short-text" # short text and numeric
|
||||
LONG_TEXT = "long-text" # strictly long text
|
||||
|
||||
|
||||
result_types = ResultType()
|
||||
|
|
|
@ -2,6 +2,8 @@ import logging
|
|||
from datetime import datetime, timedelta
|
||||
from typing import Any, List, Union
|
||||
|
||||
from felicity.apps.analysis.conf import ResultType
|
||||
|
||||
try:
|
||||
from typing import Self
|
||||
except ImportError:
|
||||
|
@ -282,6 +284,8 @@ class Analysis(BaseAuditDBModel):
|
|||
"AnalysisUncertainty", backref="analysis", lazy="selectin"
|
||||
)
|
||||
result_options = relationship("ResultOption", backref="analyses", lazy="selectin")
|
||||
# result_type : numeric, short-text, long-text (long text are a special requiring special handling)
|
||||
result_type = Column(String, default=ResultType.SHORT_TEXT, nullable=False)
|
||||
category_uid = Column(String, ForeignKey("analysis_category.uid"))
|
||||
category = relationship(AnalysisCategory, backref="analyses", lazy="selectin")
|
||||
tat_length_minutes = Column(Integer, nullable=True) # to calculate TAT
|
||||
|
|
|
@ -7,7 +7,7 @@ try:
|
|||
except ImportError:
|
||||
from typing_extensions import Self
|
||||
|
||||
from sqlalchemy import (Boolean, Column, DateTime, ForeignKey, Integer, String,
|
||||
from sqlalchemy import (Boolean, Column, DateTime, ForeignKey, Integer, String, Text,
|
||||
Table)
|
||||
from sqlalchemy.orm import relationship
|
||||
|
||||
|
@ -51,14 +51,13 @@ class AnalysisResult(Auditable, BaseMPTT):
|
|||
laboratory_instrument = relationship("LaboratoryInstrument", lazy="selectin")
|
||||
method_uid = Column(String, ForeignKey("method.uid"), nullable=True)
|
||||
method = relationship("Method", lazy="selectin")
|
||||
result = Column(String, nullable=True)
|
||||
result = Column(Text, nullable=True)
|
||||
analyst_uid = Column(String, ForeignKey("user.uid"), nullable=True)
|
||||
analyst = relationship("User", foreign_keys=[analyst_uid], lazy="selectin")
|
||||
submitted_by_uid = Column(String, ForeignKey("user.uid"), nullable=True)
|
||||
submitted_by = relationship(
|
||||
"User", foreign_keys=[submitted_by_uid], lazy="selectin"
|
||||
)
|
||||
|
||||
submitted_by_name = Column(String, nullable=True)
|
||||
date_submitted = Column(DateTime, nullable=True)
|
||||
verified_by = relationship("User", secondary=result_verification, lazy="selectin")
|
||||
|
|
|
@ -268,7 +268,7 @@ class AnalysisBase(BaseAuditModel):
|
|||
profiles: list[Profile] | None = None
|
||||
sample_types: list[SampleType] | None = None
|
||||
tat_length_minutes: int | None = None
|
||||
unit: str | None = None
|
||||
unit_uid: str | None = None
|
||||
category_uid: str | None = None
|
||||
sort_key: int | None = 0
|
||||
internal_use: bool | None = False
|
||||
|
|
|
@ -28,7 +28,7 @@ class District(LocationBase):
|
|||
province = relationship("Province", backref="districts", lazy="selectin")
|
||||
|
||||
@classmethod
|
||||
async def create(cls, district: schemas.DistrictCreate) -> schemas.District:
|
||||
async def create(cls, district: schemas.DistrictCreate):
|
||||
"""Create a new District and return the new instance."""
|
||||
exists = await cls.get(code=district.code)
|
||||
if exists:
|
||||
|
@ -36,7 +36,7 @@ class District(LocationBase):
|
|||
data = cls._import(district)
|
||||
return await super().create(**data)
|
||||
|
||||
async def update(self, district: schemas.DistrictUpdate) -> schemas.District:
|
||||
async def update(self, district: schemas.DistrictUpdate):
|
||||
"""Update the district with given data"""
|
||||
data = self._import(district)
|
||||
return await super().update(**data)
|
||||
|
@ -49,7 +49,7 @@ class Province(LocationBase):
|
|||
country = relationship("Country", backref="provinces", lazy="selectin")
|
||||
|
||||
@classmethod
|
||||
async def create(cls, province: schemas.ProvinceCreate) -> schemas.Province:
|
||||
async def create(cls, province: schemas.ProvinceCreate):
|
||||
"""Create a new province and return the new instance."""
|
||||
exists = await cls.get(code=province.code)
|
||||
if exists:
|
||||
|
@ -57,7 +57,7 @@ class Province(LocationBase):
|
|||
data = cls._import(province)
|
||||
return await super().create(**data)
|
||||
|
||||
async def update(self, province: schemas.ProvinceUpdate) -> schemas.Province:
|
||||
async def update(self, province: schemas.ProvinceUpdate):
|
||||
"""Update the province with given data"""
|
||||
data = self._import(province)
|
||||
return await super().update(**data)
|
||||
|
@ -71,7 +71,7 @@ class Country(BaseAuditDBModel):
|
|||
active = Column(Boolean(), default=False)
|
||||
|
||||
@classmethod
|
||||
async def create(cls, country: schemas.CountryCreate) -> schemas.Country:
|
||||
async def create(cls, country: schemas.CountryCreate):
|
||||
"""Create a new Country and return the new instance."""
|
||||
exists = await cls.get(code=country.code)
|
||||
if exists:
|
||||
|
@ -79,7 +79,7 @@ class Country(BaseAuditDBModel):
|
|||
data = cls._import(country)
|
||||
return await super().create(**data)
|
||||
|
||||
async def update(self, country: schemas.CountryUpdate) -> schemas.Country:
|
||||
async def update(self, country: schemas.CountryUpdate):
|
||||
"""Update the country with given data"""
|
||||
data = self._import(country)
|
||||
return await super().update(**data)
|
||||
|
|
|
@ -28,14 +28,14 @@ class Laboratory(BaseAuditDBModel):
|
|||
|
||||
@classmethod
|
||||
async def create(
|
||||
cls, obj_in: dict | schemas.LaboratoryCreate
|
||||
) -> schemas.Laboratory:
|
||||
cls, obj_in: dict | schemas.LaboratoryCreate
|
||||
):
|
||||
data = cls._import(obj_in)
|
||||
return await super().create(**data)
|
||||
|
||||
async def update(
|
||||
self, obj_in: dict | schemas.LaboratoryUpdate
|
||||
) -> schemas.Laboratory:
|
||||
self, obj_in: dict | schemas.LaboratoryUpdate
|
||||
):
|
||||
data = self._import(obj_in)
|
||||
return await super().update(**data)
|
||||
|
||||
|
@ -73,14 +73,14 @@ class LaboratorySetting(BaseAuditDBModel):
|
|||
|
||||
@classmethod
|
||||
async def create(
|
||||
cls, obj_in: dict | schemas.LaboratorySettingCreate
|
||||
) -> schemas.LaboratorySetting:
|
||||
cls, obj_in: dict | schemas.LaboratorySettingCreate
|
||||
):
|
||||
data = cls._import(obj_in)
|
||||
return await super().create(**data)
|
||||
|
||||
async def update(
|
||||
self, obj_in: dict | schemas.LaboratorySettingUpdate
|
||||
) -> schemas.LaboratorySetting:
|
||||
self, obj_in: dict | schemas.LaboratorySettingUpdate
|
||||
):
|
||||
data = self._import(obj_in)
|
||||
return await super().update(**data)
|
||||
|
||||
|
@ -94,11 +94,11 @@ class Supplier(BaseAuditDBModel):
|
|||
description = Column(String, nullable=True)
|
||||
|
||||
@classmethod
|
||||
async def create(cls, obj_in: dict | schemas.SupplierCreate) -> schemas.Supplier:
|
||||
async def create(cls, obj_in: dict | schemas.SupplierCreate):
|
||||
data = cls._import(obj_in)
|
||||
return await super().create(**data)
|
||||
|
||||
async def update(self, obj_in: dict | schemas.SupplierUpdate) -> schemas.Supplier:
|
||||
async def update(self, obj_in: dict | schemas.SupplierUpdate):
|
||||
data = self._import(obj_in)
|
||||
return await super().update(**data)
|
||||
|
||||
|
@ -113,20 +113,20 @@ class Manufacturer(BaseAuditDBModel):
|
|||
|
||||
@classmethod
|
||||
async def create(
|
||||
cls, obj_in: dict | schemas.ManufacturerCreate
|
||||
) -> schemas.Manufacturer:
|
||||
cls, obj_in: dict | schemas.ManufacturerCreate
|
||||
):
|
||||
data = cls._import(obj_in)
|
||||
return await super().create(**data)
|
||||
|
||||
async def update(
|
||||
self, obj_in: dict | schemas.ManufacturerUpdate
|
||||
) -> schemas.Manufacturer:
|
||||
self, obj_in: dict | schemas.ManufacturerUpdate
|
||||
):
|
||||
data = self._import(obj_in)
|
||||
return await super().update(**data)
|
||||
|
||||
|
||||
class Department(BaseAuditDBModel):
|
||||
"""Departrments/Sections"""
|
||||
"""Departments/Sections"""
|
||||
|
||||
__tablename__ = "department"
|
||||
|
||||
|
@ -136,14 +136,14 @@ class Department(BaseAuditDBModel):
|
|||
|
||||
@classmethod
|
||||
async def create(
|
||||
cls, obj_in: dict | schemas.DepartmentCreate
|
||||
) -> schemas.Department:
|
||||
cls, obj_in: dict | schemas.DepartmentCreate
|
||||
):
|
||||
data = cls._import(obj_in)
|
||||
return await super().create(**data)
|
||||
|
||||
async def update(
|
||||
self, obj_in: dict | schemas.DepartmentUpdate
|
||||
) -> schemas.Department:
|
||||
self, obj_in: dict | schemas.DepartmentUpdate
|
||||
):
|
||||
data = self._import(obj_in)
|
||||
return await super().update(**data)
|
||||
|
||||
|
@ -154,14 +154,13 @@ class Unit(BaseAuditDBModel):
|
|||
__tablename__ = "unit"
|
||||
|
||||
name = Column(String, nullable=False)
|
||||
# SI/Traditional Unit
|
||||
is_si_unit = Column(Boolean(), default=False)
|
||||
description = Column(String, nullable=True)
|
||||
|
||||
@classmethod
|
||||
async def create(cls, obj_in: dict | schemas.UnitCreate) -> schemas.Unit:
|
||||
async def create(cls, obj_in: dict | schemas.UnitCreate):
|
||||
data = cls._import(obj_in)
|
||||
return await super().create(**data)
|
||||
|
||||
async def update(self, obj_in: dict | schemas.UnitUpdate) -> schemas.Unit:
|
||||
async def update(self, obj_in: dict | schemas.UnitUpdate):
|
||||
data = self._import(obj_in)
|
||||
return await super().update(**data)
|
||||
|
|
|
@ -4,6 +4,7 @@ from pydantic import BaseModel, ConfigDict, EmailStr
|
|||
|
||||
from felicity.apps.common.schemas import BaseAuditModel
|
||||
|
||||
|
||||
#
|
||||
# Laboratory
|
||||
#
|
||||
|
@ -107,9 +108,7 @@ class DepartmentUpdate(DepartmentBase):
|
|||
|
||||
class DepartmentInDBBase(DepartmentBase):
|
||||
uid: str = None
|
||||
|
||||
|
||||
model_config = ConfigDict(from_attributes=True)
|
||||
model_config = ConfigDict(from_attributes=True)
|
||||
|
||||
|
||||
# Additional properties to return via API
|
||||
|
@ -129,7 +128,7 @@ class DepartmentInDB(DepartmentInDBBase):
|
|||
# Shared properties
|
||||
class UnitBase(BaseModel):
|
||||
name: str = None
|
||||
is_si_unit: bool = False
|
||||
description: str | None = None
|
||||
|
||||
|
||||
# Properties to receive via API on creation
|
||||
|
@ -144,9 +143,7 @@ class UnitUpdate(UnitBase):
|
|||
|
||||
class UnitInDBBase(UnitBase):
|
||||
uid: str = None
|
||||
|
||||
|
||||
model_config = ConfigDict(from_attributes=True)
|
||||
model_config = ConfigDict(from_attributes=True)
|
||||
|
||||
|
||||
# Additional properties to return via API
|
||||
|
@ -182,9 +179,7 @@ class SupplierUpdate(SupplierBase):
|
|||
|
||||
class SupplierInDBBase(SupplierBase):
|
||||
uid: str = None
|
||||
|
||||
|
||||
model_config = ConfigDict(from_attributes=True)
|
||||
model_config = ConfigDict(from_attributes=True)
|
||||
|
||||
|
||||
# Additional properties to return via API
|
||||
|
@ -220,9 +215,7 @@ class ManufacturerUpdate(ManufacturerBase):
|
|||
|
||||
class ManufacturerInDBBase(ManufacturerBase):
|
||||
uid: str = None
|
||||
|
||||
|
||||
model_config = ConfigDict(from_attributes=True)
|
||||
model_config = ConfigDict(from_attributes=True)
|
||||
|
||||
|
||||
# Additional properties to return via API
|
||||
|
@ -248,7 +241,6 @@ class CountryBase(BaseModel):
|
|||
|
||||
class CountryBaseInDB(CountryBase):
|
||||
uid: str | None = None
|
||||
|
||||
model_config = ConfigDict(from_attributes=True)
|
||||
|
||||
|
||||
|
|
|
@ -15,6 +15,7 @@
|
|||
"Serology",
|
||||
"Microbiology",
|
||||
"Bacteriology",
|
||||
"Virology",
|
||||
"Parasitology",
|
||||
"Microscopy",
|
||||
"Mycology",
|
||||
|
@ -188,7 +189,8 @@
|
|||
{
|
||||
"name": "HIV",
|
||||
"description": "Human Immune Virus",
|
||||
"category": "",
|
||||
"category": "Virology",
|
||||
"ucuum": "",
|
||||
"keyword": "hiv",
|
||||
"sort_key": 1,
|
||||
"active": 1,
|
||||
|
@ -202,7 +204,8 @@
|
|||
"name": "HIV Viral Load",
|
||||
"description": "HIV Viral Load",
|
||||
"category": "Molecular",
|
||||
"keyword": "hivViralLoad",
|
||||
"ucuum": "",
|
||||
"keyword": "hivVL",
|
||||
"sort_key": 1,
|
||||
"active": 1,
|
||||
"mappins": [
|
||||
|
@ -215,6 +218,7 @@
|
|||
"name": "HIV EID",
|
||||
"description": "HIV Early Infant Diagnosis",
|
||||
"category": "Molecular",
|
||||
"ucuum": "",
|
||||
"keyword": "hivEid",
|
||||
"sort_key": 1,
|
||||
"active": 1,
|
||||
|
@ -229,7 +233,7 @@
|
|||
"description": "C Reactive Protein",
|
||||
"category": "Serology",
|
||||
"ucuum": "mg/L",
|
||||
"keyword": "c_rp",
|
||||
"keyword": "c-rp",
|
||||
"sort_key": 1,
|
||||
"active": 1,
|
||||
"mappins": [
|
||||
|
@ -312,7 +316,7 @@
|
|||
"description": "Potassium",
|
||||
"category": "Clinical Chemistry",
|
||||
"ucuum": "mmol/L",
|
||||
"keyword": "potassium",
|
||||
"keyword": "POTA",
|
||||
"sort_key": 1,
|
||||
"active": 1,
|
||||
"mappins": [
|
||||
|
@ -368,6 +372,7 @@
|
|||
"description": "Blood Urea Nitrogen",
|
||||
"category": "Clinical Chemistry",
|
||||
"keyword": "urea",
|
||||
"ucuum": "",
|
||||
"sort_key": 5,
|
||||
"active": 1,
|
||||
"mappins": [
|
||||
|
@ -381,6 +386,7 @@
|
|||
"description": "Evaluates bicarbonate level; important for maintaining acid-base balance.",
|
||||
"category": "Clinical Chemistry",
|
||||
"ucuum": "mmol/L",
|
||||
"keyword": "CO2",
|
||||
"sort_key": 6,
|
||||
"active": 1,
|
||||
"mappins": [
|
||||
|
@ -1065,6 +1071,7 @@
|
|||
"name": "SI",
|
||||
"description": "Serum Iron",
|
||||
"category": "Hematology",
|
||||
"ucuum": "",
|
||||
"keyword": "SI",
|
||||
"sort_key": 1,
|
||||
"active": 1,
|
||||
|
@ -1078,6 +1085,7 @@
|
|||
"name": "TIBC",
|
||||
"description": "Total Iron-Binding Capacity",
|
||||
"category": "Hematology",
|
||||
"ucuum": "",
|
||||
"keyword": "TIBC",
|
||||
"sort_key": 1,
|
||||
"active": 1,
|
||||
|
@ -1091,6 +1099,7 @@
|
|||
"name": "FERR",
|
||||
"description": "Ferritin",
|
||||
"category": "Hematology",
|
||||
"ucuum": "",
|
||||
"keyword": "FERR",
|
||||
"sort_key": 1,
|
||||
"active": 1,
|
||||
|
@ -1104,6 +1113,7 @@
|
|||
"name": "T-Saturation",
|
||||
"description": "Transferrin Saturation",
|
||||
"category": "Hematology",
|
||||
"ucuum": "",
|
||||
"keyword": "TSat",
|
||||
"sort_key": 1,
|
||||
"active": 1,
|
||||
|
@ -1118,7 +1128,7 @@
|
|||
"description": "Troponin",
|
||||
"category": "Clinical Chemistry",
|
||||
"ucuum": "ng/mL",
|
||||
"keyword": "Troponin",
|
||||
"keyword": "Trop",
|
||||
"sort_key": 1,
|
||||
"active": 1,
|
||||
"mappins": [
|
||||
|
@ -1146,7 +1156,7 @@
|
|||
"description": "Myoglobin",
|
||||
"ucuum": "ng/mL",
|
||||
"category": "Clinical Chemistry",
|
||||
"keyword": "Myoglobin",
|
||||
"keyword": "Myogl",
|
||||
"sort_key": 1,
|
||||
"active": 1,
|
||||
"mappins": [
|
||||
|
@ -1188,7 +1198,7 @@
|
|||
"description": "pH",
|
||||
"category": "Clinical Chemistry",
|
||||
"ucuum": "",
|
||||
"keyword": "NT-proBNP",
|
||||
"keyword": "pH",
|
||||
"sort_key": 1,
|
||||
"active": 1,
|
||||
"mappins": [
|
||||
|
@ -1216,7 +1226,7 @@
|
|||
"description": "Partial Pressure of Carbon Dioxide",
|
||||
"category": "Clinical Chemistry",
|
||||
"ucuum": "mmHg",
|
||||
"keyword": "NPaCO2",
|
||||
"keyword": "PaCO2",
|
||||
"sort_key": 1,
|
||||
"active": 1,
|
||||
"mappins": [
|
||||
|
@ -1507,7 +1517,7 @@
|
|||
"description": "Lipid Panel",
|
||||
"department": "Chemistry",
|
||||
"analyses_names": [
|
||||
"TC",
|
||||
"T-C",
|
||||
"LDL",
|
||||
"HDL",
|
||||
"Trig"
|
||||
|
|
|
@ -11,7 +11,7 @@
|
|||
"Blood Bank",
|
||||
"Histology",
|
||||
"Immunology",
|
||||
"HIV",
|
||||
"Virology",
|
||||
"Cytology"
|
||||
]
|
||||
}
|
||||
|
|
|
@ -1,22 +1,4 @@
|
|||
[
|
||||
{
|
||||
"case-sensitive code": "'",
|
||||
"name (display)": "arc minute",
|
||||
"category": "Clinical",
|
||||
"synonyms": "arcminutes; arcmin; arc minutes; arc mins",
|
||||
"LOINC property": "Angle",
|
||||
"Guidance": "equal to 1/60 degree; used in optometry and opthamology (e.g. visual acuity tests)",
|
||||
"source": "UCUM"
|
||||
},
|
||||
{
|
||||
"case-sensitive code": "''",
|
||||
"name (display)": "arc second",
|
||||
"category": "Clinical",
|
||||
"synonyms": "arcseconds; arcsecs",
|
||||
"LOINC property": "Angle",
|
||||
"Guidance": "equal to 1/60 arcminute = 1/3600 degree; used in optometry and opthamology (e.g. visual acuity tests)",
|
||||
"source": "UCUM"
|
||||
},
|
||||
{
|
||||
"case-sensitive code": "%",
|
||||
"name (display)": "",
|
||||
|
@ -26,33 +8,6 @@
|
|||
"Guidance": "",
|
||||
"source": "UCUM"
|
||||
},
|
||||
{
|
||||
"case-sensitive code": "%[slope]",
|
||||
"name (display)": "percent of slope",
|
||||
"category": "Clinical",
|
||||
"synonyms": "% slope; %slope; percents slopes",
|
||||
"LOINC property": "VelFr; ElpotRatFr; VelRtoFr; AccelFr",
|
||||
"Guidance": "",
|
||||
"source": "UCUM"
|
||||
},
|
||||
{
|
||||
"case-sensitive code": "/(12.h)",
|
||||
"name (display)": "per twelve hour",
|
||||
"category": "Clinical",
|
||||
"synonyms": "per 12 hours; 12hrs; 12 hrs; /12hrs",
|
||||
"LOINC property": "Rat",
|
||||
"Guidance": "",
|
||||
"source": "LOINC"
|
||||
},
|
||||
{
|
||||
"case-sensitive code": "/[arb'U]",
|
||||
"name (display)": "per arbitrary unit",
|
||||
"category": "Clinical",
|
||||
"synonyms": "/arbU",
|
||||
"LOINC property": "InvA",
|
||||
"Guidance": "",
|
||||
"source": "LOINC"
|
||||
},
|
||||
{
|
||||
"case-sensitive code": "/[HPF]",
|
||||
"name (display)": "per high power field",
|
||||
|
@ -349,16 +304,7 @@
|
|||
"LOINC property": "Area",
|
||||
"Guidance": "the standard unit for acre used in the US and internationally",
|
||||
"source": "UCUM"
|
||||
},
|
||||
{
|
||||
"case-sensitive code": "[acr_us]",
|
||||
"name (display)": "acre - US",
|
||||
"category": "Nonclinical",
|
||||
"synonyms": "Acre USA Survey; Acre USA; survey acres",
|
||||
"LOINC property": "Area",
|
||||
"Guidance": "an older unit based on pre 1959 US statute lengths that is still sometimes used in the US only for land survey purposes.",
|
||||
"source": "UCUM"
|
||||
},
|
||||
}
|
||||
{
|
||||
"case-sensitive code": "[Amb'a'1'U]",
|
||||
"name (display)": "allergen unit for Ambrosia artemisiifolia",
|
||||
|
@ -6749,15 +6695,6 @@
|
|||
"Guidance": "unit of electric resistance",
|
||||
"source": "LOINC"
|
||||
},
|
||||
{
|
||||
"case-sensitive code": "us",
|
||||
"name (display)": "microsecond",
|
||||
"category": "Clinical",
|
||||
"synonyms": "microseconds",
|
||||
"LOINC property": "Time",
|
||||
"Guidance": "",
|
||||
"source": "LOINC"
|
||||
},
|
||||
{
|
||||
"case-sensitive code": "uU/g",
|
||||
"name (display)": "micro enzyme unit per gram",
|
||||
|
@ -6784,50 +6721,5 @@
|
|||
"LOINC property": "CCnc",
|
||||
"Guidance": "1 U is the standard enzyme unit which equals 1 micromole substrate catalyzed per minute (1 umol/min); 1 uU = 1pmol/min",
|
||||
"source": "LOINC"
|
||||
},
|
||||
{
|
||||
"case-sensitive code": "uV",
|
||||
"name (display)": "microvolt",
|
||||
"category": "Clinical",
|
||||
"synonyms": "microvolts",
|
||||
"LOINC property": "Elpot",
|
||||
"Guidance": "unit of electric potential (voltage)",
|
||||
"source": "LOINC"
|
||||
},
|
||||
{
|
||||
"case-sensitive code": "V",
|
||||
"name (display)": "volt",
|
||||
"category": "Clinical",
|
||||
"synonyms": "volts",
|
||||
"LOINC property": "Elpot",
|
||||
"Guidance": "unit of electric potential (voltage) = 1 Joule per Coulomb (J/C)",
|
||||
"source": "UCUM"
|
||||
},
|
||||
{
|
||||
"case-sensitive code": "W",
|
||||
"name (display)": "watt",
|
||||
"category": "Clinical",
|
||||
"synonyms": "watts",
|
||||
"LOINC property": "EngRat",
|
||||
"Guidance": "unit of power equal to 1 Joule per second (J/s) = kg⋅m2⋅s−3",
|
||||
"source": "UCUM"
|
||||
},
|
||||
{
|
||||
"case-sensitive code": "Wb",
|
||||
"name (display)": "weber",
|
||||
"category": "Clinical",
|
||||
"synonyms": "magnetic flux; webers",
|
||||
"LOINC property": "",
|
||||
"Guidance": "unit of magnetic flux equal to Volt second",
|
||||
"source": "UCUM"
|
||||
},
|
||||
{
|
||||
"case-sensitive code": "wk",
|
||||
"name (display)": "week",
|
||||
"category": "Clinical",
|
||||
"synonyms": "weeks; wks",
|
||||
"LOINC property": "Time",
|
||||
"Guidance": "",
|
||||
"source": "UCUM"
|
||||
}
|
||||
]
|
|
@ -2,9 +2,8 @@ import logging
|
|||
from datetime import datetime
|
||||
from typing import Optional
|
||||
|
||||
from apps.setup.models.setup import Department
|
||||
from felicity.apps.analysis import utils
|
||||
from felicity.apps.analysis.models.analysis import (Analysis, AnalysisCategory,
|
||||
from felicity.apps.analysis.models.analysis import (Analysis, analysis_profile, AnalysisCategory,
|
||||
CodingStandard, Profile,
|
||||
RejectionReason,
|
||||
SampleType)
|
||||
|
@ -15,14 +14,33 @@ from felicity.apps.analysis.schemas import (AnalysisCategoryCreate,
|
|||
RejectionReasonCreate,
|
||||
SampleTypeCreate)
|
||||
from felicity.apps.common.models import IdSequence
|
||||
from felicity.apps.setup.models.setup import Department
|
||||
from felicity.apps.setup.models.setup import Unit
|
||||
from felicity.apps.setup.schemas import UnitCreate
|
||||
from felicity.core.config import get_settings
|
||||
from felicity.database.session import async_session_factory
|
||||
from .data import get_seeds
|
||||
|
||||
settings = get_settings()
|
||||
logging.basicConfig(level=logging.INFO)
|
||||
logger = logging.getLogger(__name__)
|
||||
|
||||
units = {}
|
||||
|
||||
|
||||
async def unit_resolver(name: str, description=""):
|
||||
if not name or name is None:
|
||||
return None
|
||||
|
||||
if name in units:
|
||||
return units[name]
|
||||
|
||||
unit = await Unit.get(name=name)
|
||||
if not unit:
|
||||
unit_in = UnitCreate(name=name, descritpion=description)
|
||||
unit = await Unit.create(unit_in)
|
||||
units[name] = unit
|
||||
return unit
|
||||
|
||||
|
||||
async def seed_categories():
|
||||
logger.info("Setting up analyses categories .....")
|
||||
|
@ -119,12 +137,14 @@ async def seed_analyses_services_and_profiles() -> None:
|
|||
|
||||
for _anal in analyses:
|
||||
analyte: Optional[Analysis] = await Analysis.get(name=_anal.get("name"))
|
||||
category = await AnalysisCategory.get(name=_anal.get("category"))
|
||||
if not analyte:
|
||||
category = await AnalysisCategory.get(name=_anal.get("category"))
|
||||
unit = await unit_resolver(name=_anal.get("ucuum"))
|
||||
an_in = AnalysisCreate(
|
||||
name=_anal.get("name"),
|
||||
description=_anal.get("description"),
|
||||
category_uid=category.uid if category else None,
|
||||
unit_uid=unit.uid if unit else None,
|
||||
keyword=_anal.get("keyword"),
|
||||
sort_key=_anal.get("sort_key"),
|
||||
active=bool(_anal.get("active")),
|
||||
|
@ -136,31 +156,27 @@ async def seed_analyses_services_and_profiles() -> None:
|
|||
|
||||
for _prf in profiles:
|
||||
a_profile: Optional[Profile] = await Profile.get(name=_prf.get("name"))
|
||||
department = await Department.get(name=_prf.get("department"))
|
||||
if not a_profile:
|
||||
department = await Department.get(name=_prf.get("department"))
|
||||
prof_in = ProfileCreate(
|
||||
name=_prf.get("name"),
|
||||
description=_prf.get("description"),
|
||||
department_uid=_prf.get("department")
|
||||
department_uid=department.uid if department else None
|
||||
)
|
||||
a_profile = await Profile.create(prof_in)
|
||||
|
||||
analyses_names = _prf.get("analyses_names", [])
|
||||
for _a_name in analyses_names:
|
||||
anal: Optional[Analysis] = await Analysis.get(name=_a_name)
|
||||
if anal:
|
||||
profiles = await Profile.get_all(analyses___uid=anal.uid)
|
||||
if a_profile.uid not in [profile.uid for profile in profiles]:
|
||||
logger.info(f"adding anal: {anal} to profile: {a_profile}")
|
||||
a_profile.analyses.append(anal)
|
||||
await a_profile.save_async()
|
||||
|
||||
async with async_session_factory() as session:
|
||||
try:
|
||||
await session.flush()
|
||||
await session.commit()
|
||||
except Exception: # noqa
|
||||
await session.rollback()
|
||||
anal = await Analysis.get(name=_a_name)
|
||||
if anal and anal.uid not in [a.uid for a in a_profile.analyses]:
|
||||
a_profile.analyses.append(anal)
|
||||
await Profile.table_insert(
|
||||
analysis_profile,
|
||||
mappings={
|
||||
"analysis_uid": anal.uid,
|
||||
"profile_uid": a_profile.uid
|
||||
}
|
||||
)
|
||||
|
||||
await utils.billing_setup_profiles([a_profile.uid])
|
||||
|
||||
|
|
2350
felicity/migrations/versions/65f077efa77b_init_db.py
Normal file
2350
felicity/migrations/versions/65f077efa77b_init_db.py
Normal file
File diff suppressed because it is too large
Load diff
|
@ -70,7 +70,7 @@ export const GET_ALL_ANALYSES_SERVICES = gql`
|
|||
unit {
|
||||
uid
|
||||
name
|
||||
isSiUnit
|
||||
description
|
||||
}
|
||||
min
|
||||
max
|
||||
|
@ -253,7 +253,7 @@ export const GET_ALL_ANALYSES_PROFILES_AND_SERVICES = gql`
|
|||
unit {
|
||||
uid
|
||||
name
|
||||
isSiUnit
|
||||
description
|
||||
}
|
||||
min
|
||||
max
|
||||
|
|
|
@ -272,7 +272,7 @@ export const ADD_UNIT = gql`
|
|||
... on UnitType {
|
||||
uid
|
||||
name
|
||||
isSiUnit
|
||||
description
|
||||
}
|
||||
|
||||
... on OperationError {
|
||||
|
@ -290,7 +290,7 @@ export const EDIT_UNIT = gql`
|
|||
... on UnitType {
|
||||
uid
|
||||
name
|
||||
isSiUnit
|
||||
description
|
||||
}
|
||||
|
||||
... on OperationError {
|
||||
|
|
|
@ -136,7 +136,7 @@ export const GET_ALL_UNITS = gql`
|
|||
unitAll {
|
||||
uid
|
||||
name
|
||||
isSiUnit
|
||||
description
|
||||
}
|
||||
}
|
||||
`;
|
||||
|
|
|
@ -111,5 +111,5 @@ export interface IDepartment {
|
|||
export interface IUnit {
|
||||
uid?: string;
|
||||
name?: string;
|
||||
isSiUnit?: boolean;
|
||||
description?: string;
|
||||
}
|
||||
|
|
|
@ -206,7 +206,7 @@ function saveMappingForm(): void {
|
|||
<hr />
|
||||
|
||||
<div class="grid grid-cols-12 gap-4 mt-2">
|
||||
<section class="col-span-3 overflow-y-scroll overscroll-contain patient-scrol">
|
||||
<section class="col-span-3 overflow-y-scroll overscroll-contain max-h-[540px]">
|
||||
<ul>
|
||||
<li
|
||||
v-for="profile in analysesProfiles"
|
||||
|
|
|
@ -212,7 +212,7 @@ function saveMappingForm(): void {
|
|||
<hr />
|
||||
|
||||
<div class="grid grid-cols-12 gap-4 mt-2">
|
||||
<section class="col-span-2 overflow-y-scroll overscroll-contain analyses-scroll bg-white p-1">
|
||||
<section class="col-span-2 overflow-y-scroll overscroll-contain max-h-[540px] bg-white p-1">
|
||||
<div class="w-full">
|
||||
<accordion v-for="category in analysesServices" :key="category[0]">
|
||||
<template v-slot:title>{{ category[0] }}</template>
|
||||
|
|
|
@ -21,13 +21,13 @@
|
|||
let unit = reactive({}) as IUnit;
|
||||
|
||||
function addUnit(): void {
|
||||
const payload = { name: unit.name, isSiUnit: unit.isSiUnit == true }
|
||||
const payload = { name: unit.name, description: unit.description }
|
||||
withClientMutation(ADD_UNIT, { payload }, "createUnit")
|
||||
.then((result) => setupStore.addUnit(result));
|
||||
}
|
||||
|
||||
function editUnit(): void {
|
||||
const payload = { name: unit.name, isSiUnit: unit.isSiUnit == true }
|
||||
const payload = { name: unit.name, description: unit.description }
|
||||
withClientMutation(EDIT_UNIT, { uid: unit.uid, payload }, "updateUnit")
|
||||
.then((result) => setupStore.updateUnit(result));
|
||||
}
|
||||
|
@ -114,7 +114,7 @@
|
|||
<label class="block col-span-2 my-2">
|
||||
<input
|
||||
type="checkbox"
|
||||
v-model="unit.isSiUnit"
|
||||
v-model="unit.description"
|
||||
/>
|
||||
<span class="text-gray-700 ml-4">Is SI Unit</span>
|
||||
</label>
|
||||
|
|
|
@ -123,7 +123,7 @@ const accordion = defineAsyncComponent(
|
|||
<hr />
|
||||
|
||||
<div class="grid grid-cols-12 gap-4 mt-2">
|
||||
<section class="col-span-3 overflow-y-scroll overscroll-contain patient-scrol">
|
||||
<section class="col-span-3 overflow-y-scroll overscroll-contain max-h-[540px]">
|
||||
<ul>
|
||||
<li
|
||||
v-for="group in groups"
|
||||
|
|
Loading…
Reference in a new issue