diff --git a/nbri_ehr/resources/data/birth_condition.tsv b/nbri_ehr/resources/data/birth_condition.tsv
new file mode 100644
index 0000000..bdb4e26
--- /dev/null
+++ b/nbri_ehr/resources/data/birth_condition.tsv
@@ -0,0 +1,3 @@
+value title sort_order
+L Live 1
+D Dead 2
diff --git a/nbri_ehr/resources/data/breeding_type.tsv b/nbri_ehr/resources/data/breeding_type.tsv
new file mode 100644
index 0000000..dea0f78
--- /dev/null
+++ b/nbri_ehr/resources/data/breeding_type.tsv
@@ -0,0 +1,10 @@
+value title sort_order
+A Assigned Breeding Protocol 1
+C Cull 2
+H Held from Mating Activity 3
+M Multi-Male 4
+P Project Breeding 5
+Q Testing as Breeder 6
+S Single Male Harem 7
+T Time-Mated 8
+O Not Assigned 9
\ No newline at end of file
diff --git a/nbri_ehr/resources/data/delivery_mode.tsv b/nbri_ehr/resources/data/delivery_mode.tsv
new file mode 100644
index 0000000..cea8a58
--- /dev/null
+++ b/nbri_ehr/resources/data/delivery_mode.tsv
@@ -0,0 +1,4 @@
+value title
+V Vaginal
+N Surgical-clinical
+NX Surgical experimental
\ No newline at end of file
diff --git a/nbri_ehr/resources/data/editable_lookups.tsv b/nbri_ehr/resources/data/editable_lookups.tsv
index 90cc8af..1323d7b 100644
--- a/nbri_ehr/resources/data/editable_lookups.tsv
+++ b/nbri_ehr/resources/data/editable_lookups.tsv
@@ -18,10 +18,12 @@ ehr_lookups bcs_score Clinical Body Condition Score Clinical observation fixed v
ehr_lookups behavior_abnormality Clinical Behavior Abnormality Clinical observation fixed values.
ehr_lookups behavior_mgmt_codes Behavior Behavior Management Codes Behavior observation fixed values.
ehr_lookups behavior_types Behavior Behavior Types Behavior observation fixed values.
+ehr_lookups birth_condition Colony Management Birth Condition Birth condition values.
ehr_lookups blood_draw_reason Clinical Blood Draw Reason Used in blood draw datasets.
ehr_lookups blood_draw_tube_type Clinical Blood Draw Tube Type Used in blood draw datasets.
ehr_lookups blood_sample_type Clinical Blood Sample Types Used in blood draw datasets.
ehr_lookups blood_tube_volumes Clinical Blood Tube Volumes Used in blood draw datasets.
+ehr_lookups breeding_type Colony Management Breeding Type Breeding group assignment codes.
ehr_lookups cage_type Colony Management Cage Type Used in cage details.
ehr_lookups calculated_status_codes Colony Management Calculated Status Animal status values.
ehr_lookups capillary_refill_time Clinical Capillary Refill Times Used clinical observations.
@@ -37,6 +39,7 @@ ehr_lookups country_category Colony Management Country Category
ehr_lookups daily_enrich_codes Behavior Daily enrichment codes.
ehr_lookups data_category Clinical Data Categories Used in datasets.
ehr_lookups death_reason Colony Management Death Reason
+ehr_lookups delivery_mode Colony Management Delivery Mode
ehr_lookups delivery_state Colony Management Delivery State
ehr_lookups dental_obs Clinical Dental Observation Types Clinical observation values.
ehr_lookups derm_obs Clinical Dermatologic Observation Types Clinical observation values.
@@ -61,6 +64,7 @@ ehr_lookups general_obs Clinical General Observation Types Clinical observation
ehr_lookups genital_types Colony Management Genital Types Clinical observation fixed values.
ehr_lookups genitourinary_obs Clinical Genitourinary Observation Types Clinical observation fixed values.
ehr_lookups geographic_origins Colony Management Geographic Origins Used in demographics dataset.
+ehr_lookups group_status Colony Management Group Status Group assignment status codes.
ehr_lookups hernia_types Clinical Hernia Types Clinical observation fixed values.
ehr_lookups housing_reason Housing Housing Move Reason Used in housing dataset for location transfers.
ehr_lookups hyd_score Clinical Hydration Score Clinical observation fixed values.
diff --git a/nbri_ehr/resources/data/gender_codes.tsv b/nbri_ehr/resources/data/gender_codes.tsv
index 01c67fb..a55c8a7 100644
--- a/nbri_ehr/resources/data/gender_codes.tsv
+++ b/nbri_ehr/resources/data/gender_codes.tsv
@@ -1,4 +1,4 @@
code meaning
-1 unknown
-2 female
-3 male
\ No newline at end of file
+U Unknown
+F Female
+M Male
\ No newline at end of file
diff --git a/nbri_ehr/resources/data/lookup_sets.tsv b/nbri_ehr/resources/data/lookup_sets.tsv
index 613eb8e..993844b 100644
--- a/nbri_ehr/resources/data/lookup_sets.tsv
+++ b/nbri_ehr/resources/data/lookup_sets.tsv
@@ -16,8 +16,10 @@ bcs_score BCS Store value title
behavior_abnormality Behavior Abnormality value
behavior_mgmt_codes Behavior Management Codes value
behavior_types Behavior Types value
+birth_condition Birth Condition value title
blood_draw_reason Blood Draw Reason value
blood_sample_type Blood Sample Types value
+breeding_type Breeding Type value title
cage_type Cage Type value title
capillary_refill_time Capillary Refill Time value
card_format Card Format value title
@@ -31,6 +33,7 @@ country_category Country Category value title
daily_enrich_codes Daily Enrichment Codes value
data_category Data Category Field Values value
death_reason Death Reason value
+delivery_mode Delivery Mode value title
delivery_state Delivery State value title
dental_obs Dental Observations value
derm_obs Dermatologic Observations value
@@ -48,6 +51,7 @@ gastro_types Gastrointestinal Types value
general_obs General Observations value
genital_types Genital Types value
genitourinary_obs Genitourinary Observations value
+group_status Group Status value title
hernia_types Hernia Types value
housing_reason Housing Reason value
hyd_score Hyd Score value
@@ -98,6 +102,7 @@ req_order_type Req Order Type value title
respiratory_observations Respiratory Observations value title
sib_score SIB Score value
skin_problem Skin Problem value
+status_codes Status Code Field Values value title
stool_score Stool Score value
stool_types Stool Types value
tb_obs_score TB Obs Score value
diff --git a/nbri_ehr/resources/data/lookupsManifest.tsv b/nbri_ehr/resources/data/lookupsManifest.tsv
index defb466..0dbf034 100644
--- a/nbri_ehr/resources/data/lookupsManifest.tsv
+++ b/nbri_ehr/resources/data/lookupsManifest.tsv
@@ -18,10 +18,12 @@ bcs_score
behavior_abnormality
behavior_mgmt_codes
behavior_types
+birth_condition
blood_draw_reason
blood_draw_tube_type
blood_sample_type
blood_tube_volumes
+breeding_type
cage_type
calculated_status_codes
capillary_refill_time
@@ -35,6 +37,7 @@ country_category
daily_enrich_codes
data_category
death_reason
+delivery_mode
delivery_state
dental_obs
derm_obs
@@ -57,6 +60,7 @@ general_obs
genital_types
genitourinary_obs
geographic_origins
+group_status
hernia_types
housing_reason
hyd_score
@@ -109,6 +113,7 @@ sib_score
source
snomed
skin_problem
+status_codes
stool_score
stool_types
tb_obs_score
diff --git a/nbri_ehr/resources/data/lookupsManifestTest.tsv b/nbri_ehr/resources/data/lookupsManifestTest.tsv
index b2006c8..51c43a4 100644
--- a/nbri_ehr/resources/data/lookupsManifestTest.tsv
+++ b/nbri_ehr/resources/data/lookupsManifestTest.tsv
@@ -17,10 +17,12 @@ bcs_score
behavior_abnormality
behavior_mgmt_codes
behavior_types
+birth_condition
blood_draw_reason
blood_draw_tube_type
blood_sample_type
blood_tube_volumes
+breeding_type
cage_type
calculated_status_codes
capillary_refill_time
@@ -34,6 +36,7 @@ country_category
daily_enrich_codes
data_category
death_reason
+delivery_mode
delivery_state
dental_obs
derm_obs
@@ -56,6 +59,7 @@ general_obs
genital_types
genitourinary_obs
geographic_origins
+group_status
hernia_types
housing_reason
hyd_score
diff --git a/nbri_ehr/resources/data/pregnancy_result.tsv b/nbri_ehr/resources/data/pregnancy_result.tsv
index 1c615bc..819182e 100644
--- a/nbri_ehr/resources/data/pregnancy_result.tsv
+++ b/nbri_ehr/resources/data/pregnancy_result.tsv
@@ -1,3 +1,7 @@
value title
-1 Stillborn
-2 Abort
\ No newline at end of file
+NT No Tissue
+FD Fetal Death
+FN Found at necropsy
+FX Live, Term, euthanized at birth
+ND Live, Died day of birth (lungs inflated)
+FL Fetal Delivery, live in Utero
\ No newline at end of file
diff --git a/nbri_ehr/resources/data/source.tsv b/nbri_ehr/resources/data/source.tsv
index 0d893c4..8dc42a1 100644
--- a/nbri_ehr/resources/data/source.tsv
+++ b/nbri_ehr/resources/data/source.tsv
@@ -1,108 +1,103 @@
code meaning
-1 Adv Bioscience Labs
-2 Alamogordo PrimateFaclty
-3 Alpha Genesis, Inc.
-4 Barton West End Farm
-5 Battelle Memorial Inst
-6 Baylor Research Inst
-7 BIOCULTURE (MTIUS) LTD
-8 Bioculture US LLC
-9 BIOQUAL, Inc.
-10 Boehringer Ingelheim
-11 Boston University
-12 Buckshire Corporation
-13 Caribbean Primate Rsrch
-14 CBNC
-15 CDC
-16 Charles River Laboratory
-17 Charles River/Reno
-18 Chimp Haven
-19 China/Guangxi GF Sci Pri
-20 Chiron Corp
-21 CiToxLab North America
-22 Covance Research Prod
-23 CR Rsrch Models Houston
-24 Ctr Captive Chimp Care
-25 Cynologics Ltd
-26 DHMRI
-27 Duke Univ Medical Ctr
-28 Durham Research Center
-29 Emory University YPRC
-30 Envigo Global Services
-31 Guangdong Landau Biotech
-32 Hainan, China
-33 Harvard Medical School
-34 Indonesia (Pt. W. Sat)
-35 Johns Hopkins University
-36 LC Preclinical Research
-37 Lovelace Biomedical
-38 LRRI
-39 LSU Health Science BR
-40 LSU Health Science NO
-41 LSU Health Science Shv
-42 Mannheimer Foundation
-43 Mass. General Hospital
-44 MD Anderson Cancer Ctr.
-45 Merck & Co (Rahway)
-46 Merck & Co (WP)
-47 Merck Research Labs WP
-48 Nationwide Children's
-49 New England NPRC
-50 New York University
-51 NIAID (Bioqual)
-52 NIAID Morgan Island
-53 NIAID NIH Animal Ctr
-54 NICHD/NIH
-55 NIH
-56 NIH Animal Center
-57 NINDS NIH Animal Ctr
-58 Novartis Pharm. Corp.
-59 Novartis Vaccines Srl
-60 NYU School of Medicine
-61 Oregon NPRC
-62 Pfizer
-63 Pfizer-Andover
-64 Pfizer-Pearl River
-65 PreLabs
-66 Primate Products
-67 Primedica Labs
-68 PrimGen
-69 Primgen CSP
-70 RainForest Adventures
-71 Republic of Mauritius
-72 Rocky Mountain Lab
-73 Save the Chimps
-74 Siconbrec Inc
-75 Sierra Biomedical
-76 SNBL-SRC
-77 SRI International
-78 St. Jude Childrens Rsrch
-79 St. Kitts
-80 Stanford Univ School Med
-81 Stony Brook University
-82 SUNY Downstate Medical
-83 SW Found Biomed Rsrch
-84 Texas Biomed
-85 Three Springs Scientific
-86 Tulane NPC (Covington)
-87 Tulane Univ Medical Ctr
-88 Univ Alabama Birmingham
-89 Univ of Illinois
-90 Univ of Kansas Med Ctr
-91 Univ of Maryland
-92 Univ of Nebraska Med Ctr
-93 Univ of Pittsburgh
-94 Univ of Texas at Austin
-95 Univ of Washington NPRC
-96 Univ of Wisconsin
-97 Univ Tex MD Anderson CC
-98 USAMRICD
-99 USAMRIID
-100 Virginia Commonwealth U
-101 WakeForest School of Med
-102 WaNPRC
-103 Worldwide Primates, Inc.
-104 WRAIR
-105 Wyeth-Ayerst Rsrch (PR)
-106 Yale Univ Sch Medicine
-107 Yerkes Regional PRC
\ No newline at end of file
+AAI ASIATIC ANIMAL IMPORTS
+BIOQUAL BIOQUAL, INCORPORATED
+BRANDEIS BRANDEIS UNIVERSITY
+CA-DPH CALIF DEPT PUBLIC HEALTH FACILITIES
+CA-DOH CALIFORNIA STATE DEPARTMENT OF HEALTH
+CPRC CARRIBEAN PRIMATE CENTER
+CWRU CASE WESTERN RESERVE UNIVERSITY
+UCD-CNS CENTER FOR NEUROSCIENCE, UCD
+CR-KL CHARLES RIVER - KEY LOIS
+CRL CHARLES RIVER LABS
+CRRP CHARLES RIVER RESEARCH PRIMATES INC
+BROOKFIELD CHICAGO ZOOLOGICAL PARK (BROOKFIELD ZOO)
+CHILDRENS CHILDRENS HOSPITAL
+CHIMR CHRIST HOSPITAL INST. FOR MEDICAL RES.
+CSU COLORADO STATE UNIVERSITY
+CORNELL CORNELL UNIVERSITY
+COULSTON COULSTON FOUNDATION
+COVANCE COVANCE RESEARCH PRODUCTS, INC.
+PRIMGEN CSP-PRIMGEN
+CUTTER CUTTER LAB
+DMT DEL MUNDO TRADING
+EPZ EL PASO ZOOLOGICAL GARDENS
+ENVIGO ENVIGO
+HAHNEMANN HAHNEMANN UNIVERSITY
+HL HAZELTON LABORATORIES
+HLA HAZELTON LABORATORIES AMERICA INC.
+UNK INSTITUTION UNKNOWN
+ISU-VDL IOWA STATE UNIV, VET DIAGNOSTIC LAB
+JVL JAN VACEK LIMITED
+JHMC JEWISH HOSPITAL & MEDICAL CENTER
+JRI JOHNSON RESEARCH INSTITUTE
+KNLPC KUNMING NATIONAL LABORATORY PRIMATE CTR.
+LABS LABORATORY ANIMAL BREEDERS AND SERVICES
+LABSINDO LABSINDO
+LEMSIP LEMSIP, NEW YORK MEDICAL CENTER, RDI
+LAIR LETTERMAN ARMY RES INST-PRESIDIO
+LB LITTON BIONETICS
+LLU LOMA LINDA UNIVERSITY
+MSU-MI MICHIGAN STATE UNIVERSITY
+MSU-MT MONTANA STATE UNIVERSITY
+MPI MPI RESEARCH
+NASA-ARC NASA-AMES RESEARCH CENTER
+NAMRL NAVAL AEROSPACE MEDICAL RESEARCH LAB
+NEPRC NEW ENGLAND PRIMATE RESEARCH CENTER
+NIHAC NIH ANIMAL CENTER
+ORPRC OREGON REGIONAL PRIMATE RESEARCH CENTER
+PARC-SAF PARC SAFARI AFRICAN
+PPC PERRINE PRIMATE CENTER
+PPP PERUVIAN PRIMATOLOGICAL PROJECT
+PET-FARM PET FARM
+PRIMLAB PRIMATE LABORATORY
+PPI PRIMATE PRODUCTS, INCORPORATED
+PRIVATE PRIVATE PARTY
+RIEPT RES. INST. OF EXP. PATHOLOGY & THERAPY
+SALK SALK INSTITUTE
+SFGH SAN FRANCISCO GENERAL HOSPITAL
+SNBL SHIN NIPPON BIOMEDICAL LABORATORIES
+SICONBREC SICONBREC
+SBM SIERRA BIOMEDICAL
+SKB SMITH, KLINE, BEECHAM
+SIU SOUTHERN ILLINOIS UNIVERSITY
+SIU-SOM SOUTHERN ILLINOIS UNIVERSITY MED SCHOOL
+SORI SOUTHERN RESEARCH INSTITUTE
+SFRE SOUTHWEST FOUNDATION FOR RES. & EDUC.
+SWRF SOUTHWEST RESEARCH FOUNDATION
+SWRI SOUTHWEST RESEARCH INSTITUTE
+SOPF STANFORD OUTDOOR PRIMATE FACILITY
+SRI STANFORD RESEARCH INSTITUTE
+SUNY-SB STATE UNIV OF NEW YORK AT STONY BROOK
+SXZ SUZHOU XISHAN ZHONGKE LAB ANIMAL CO.
+SYNTEX SYNTEX (USA) INCORPORATED
+TARPON TARPON ZOO
+TTUHSC TEXAS TECH HEALTH SCIENCE CENTER
+BROOKS-AFB TEXAS, BROOKS AIR FORCE BASE
+TPI THE PARKINSON'S INSTITUTE
+TNPRC TULANE (DELTA) REGIONAL PRIMATE RES CTR
+UCB UC BERKELEY
+UCLA UC LOS ANGELES
+UCR UC RIVERSIDE
+UCSD UC SAN DIEGO
+UCSF UC SAN FRANCISCO VIVARIUM
+UC-ARS UNIV OF CALIF, ANIMAL RESOURCES SERVICE
+GPC UNIV OF GOTTINGEN PRIMATE CENTER
+UH-RAF UNIV OF HAWAII, RESEARCH ANIMAL FACILITY
+OUHSC UNIV OF OKLAHOMA HEALTH SCI. CENTER
+UTHSC-H UNIV OF TEXAS, HEALTH SCI CTR, HOUSTON
+UCHSC UNIVERSITY OF COLORADO HEALTH SCIENCES
+UCMC UNIVERSITY OF COLORADO MEDICAL CENTER
+UIC UNIVERSITY OF ILLINOIS AT CHICAGO
+UNV UNIVERSITY OF NEVADA
+UNM UNIVERSITY OF NEW MEXICO
+UPR UNIVERSITY OF PUERTO RICO
+UTSCC UNIVERSITY OF TEXAS SYSTEM CANCER CENTER
+UNK-CN UNKNOWN INSTITUTION, CHINA
+VBS VALLEY BIOSYSTEMS
+WFSM WAKE FOREST SCHOOL OF MEDICINE
+WANPRC WASHINGTON REGIONAL PRIMATE RESEARCH CTR
+WHMC WILFORD HALL MEDICAL CENTER
+WRPRC WISCONSIN REGIONAL PRIMATE RESEARCH CTR
+WAI WOODWARD ASIATIC IMPORTS
+WWP WORLD WIDE PRIMATES, INC.
+YPRC YEMASSEE PRIMATE RESEARCH CENTER
diff --git a/nbri_ehr/resources/data/species.tsv b/nbri_ehr/resources/data/species.tsv
index c95e4bd..12d3118 100644
--- a/nbri_ehr/resources/data/species.tsv
+++ b/nbri_ehr/resources/data/species.tsv
@@ -1,7 +1,15 @@
Common Scientific Name Id Prefix Mhc Prefix Max Blood Draw (mL/kg) Max Percent Blood Drawn Blood Reconstitution Interval (Days) Cites Code Date Disabled USDA Gestation
-African Green Monkey Chlorocebus aethiops AGM 3.0000 1.0000 7.0000
-Brown-Tufted Capuchin Cebus apella CAP 3.0000 1.0000 7.0000
-Cynomolgus Macaque Macaca fascicularis CYN 3.0000 1.0000 7.0000
-Marmoset 3.0000 1.0000 7.0000
-Pig-Tailed Macaque Macaca nemestrina PIG 3.0000 1.0000 7.0000
-Rhesus Macaque Macaca mulatta RHM 3.0000 1.0000 7.0000
\ No newline at end of file
+Rhesus Macaque Macaca Mulatta 3.0000 1.0000 7.0000
+Pig-Tailed Macaque Macaca Nemestrina 3.0000 1.0000 7.0000
+Bonnet Macaque Macaca Radiata 3.0000 1.0000 7.0000
+Olive Baboon Papio Anubis 3.0000 1.0000 7.0000
+Yellow Baboon Papio Cynocephalus 3.0000 1.0000 7.0000
+Squirrel Monkey Saimiri Sciureus 3.0000 1.0000 7.0000
+African Green Monkey Chlorocebus Aethiops 3.0000 1.0000 7.0000
+Domestic Dog Canis Familiaris 3.0000 1.0000 7.0000
+Formosan Rock Macaque Macaca Cyclopis 3.0000 1.0000 7.0000
+Japanese Macaque Macaca Fuscata 3.0000 1.0000 7.000
+Talapoin Monkey Cercopithecus Talapoin 3.0000 1.0000 7.0000
+Sykes' Monkey Cercopithecus M Albogulari 3.0000 1.0000 7.0000
+Dusky Titi Monkey Callicebus Moloch 3.0000 1.0000 7.0000
+Brown-Tufted Capuchin Cebus Apella 3.0000 1.0000 7.0000
\ No newline at end of file
diff --git a/nbri_ehr/resources/data/species_codes.tsv b/nbri_ehr/resources/data/species_codes.tsv
index df698e7..feb4100 100644
--- a/nbri_ehr/resources/data/species_codes.tsv
+++ b/nbri_ehr/resources/data/species_codes.tsv
@@ -1,7 +1,15 @@
Code Scientific Name Common Name Description Genus Species Date Disabled
-1 Chlorocebus aethiops AGM African Green Monkey 3
-10 Macaca mulatta RHM Rhesus Macaque 3
-18 Marmoset 3
-4 Cebus apella CAP Brown-Tufted Capuchin 3
-7 Macaca fascicularis CYN Cynomolgus Macaque 3
-9 Macaca nemestrina PIG Pig-Tailed Macaque 3
\ No newline at end of file
+MMU Macaca Mulatta Rhesus Macaque
+MNE Macaca Nemestrina Pig-Tailed Macaque
+MRA Macaca Radiata Bonnet Macaque
+PAN Papio Anubis Olive Baboon
+PCY Papio Cynocephalus Yellow Baboon
+SSC Saimiri Sciureus Squirrel Monkey
+CAE Chlorocebus Aethiops African Green / Vervet
+DOG Canis Familiaris Domestic Dog
+MCY Macaca Cyclopis Formosan Rock Macaque
+MFU Macaca Fuscata Japanese Macaque
+CTA Cercopithecus Talapoin Talapoin Monkey
+CMA Cercopithecus M Albogulari Sykes' Monkey
+CMO Callicebus Moloch Dusky Titi Monkey
+CAP Cebus Apella Brown-Tufted Capuchin
\ No newline at end of file
diff --git a/nbri_ehr/resources/data/status_codes.tsv b/nbri_ehr/resources/data/status_codes.tsv
new file mode 100644
index 0000000..b131086
--- /dev/null
+++ b/nbri_ehr/resources/data/status_codes.tsv
@@ -0,0 +1,5 @@
+value title
+Alive Alive
+Dead Dead
+Escaped Escaped
+Shipped Shipped
diff --git a/nbri_ehr/resources/queries/ehr/project.query.xml b/nbri_ehr/resources/queries/ehr/project.query.xml
index d2db2ca..5b72f21 100644
--- a/nbri_ehr/resources/queries/ehr/project.query.xml
+++ b/nbri_ehr/resources/queries/ehr/project.query.xml
@@ -47,6 +47,13 @@
true
+
+
+ core
+ Users
+ UserId
+ DisplayName
+ true
diff --git a/nbri_ehr/resources/queries/nbri_ehr/Conception.query.xml b/nbri_ehr/resources/queries/nbri_ehr/Conception.query.xml
index 0eb26a8..7fc6298 100644
--- a/nbri_ehr/resources/queries/nbri_ehr/Conception.query.xml
+++ b/nbri_ehr/resources/queries/nbri_ehr/Conception.query.xml
@@ -14,16 +14,28 @@
Conception Date
-
- Conception Date
- Conception Term Date
+
+ Estimated
+ Conception date is estimated rather than observed
+ true
+
+ Task Id
+ ALWAYS_OFF
+
+ ehr
+ tasks
+ taskid
+ rowid
+
+ /ehr/dataEntryFormDetails.view?formType=${TaskId/formtype}&taskid=${TaskId}
+ Status
@@ -31,6 +43,62 @@
qcstaterowid
+
+
+
+
+
+ FBEC5D
+
+
+
+
+
+ FBEC5D
+
+
+
+
+
+ FBEC5D
+
+
+
+
+
+ FF0000
+
+
+
+
+
+ FBEC5D
+
+
+
+
+
+ FBEC5D
+
+
+
+
+
+ FF0000
+
+
+
+
+
+ FBEC5D
+
+
+
+
+
+ FBEC5D
+
+
diff --git a/nbri_ehr/resources/queries/nbri_ehr/ConceptionsByDam.query.xml b/nbri_ehr/resources/queries/nbri_ehr/ConceptionsByDam.query.xml
index 866a7da..8dac93d 100644
--- a/nbri_ehr/resources/queries/nbri_ehr/ConceptionsByDam.query.xml
+++ b/nbri_ehr/resources/queries/nbri_ehr/ConceptionsByDam.query.xml
@@ -11,9 +11,17 @@
Conception Id
+
+ Estimated
+ Conception date is estimated rather than observed
+ Conception Outcome
+
+ Offspring
+ Animals born from this conception, if a birth record references it
+
diff --git a/nbri_ehr/resources/queries/nbri_ehr/ConceptionsByDam.sql b/nbri_ehr/resources/queries/nbri_ehr/ConceptionsByDam.sql
index 4554f1d..2890410 100644
--- a/nbri_ehr/resources/queries/nbri_ehr/ConceptionsByDam.sql
+++ b/nbri_ehr/resources/queries/nbri_ehr/ConceptionsByDam.sql
@@ -8,16 +8,18 @@ SELECT
c.ConceptId,
c.ConceptDate,
c.ConceptTermDate,
+ c.Estimated,
c.Sire,
CASE
WHEN b.conceptId IS NOT NULL THEN 'Live Birth'
WHEN po.conceptId IS NOT NULL THEN COALESCE(po.result, 'Unknown')
ELSE 'Unknown'
END AS conceptionOutcome,
+ b.offspring,
c.Remark,
c.QCState AS qcstate
FROM Conception c
-LEFT JOIN (SELECT DISTINCT b.conceptId FROM study.birth b WHERE b.conceptId IS NOT NULL) b
+LEFT JOIN (SELECT b.conceptId, GROUP_CONCAT(DISTINCT b.Id, ', ') AS offspring FROM study.birth b WHERE b.conceptId IS NOT NULL GROUP BY b.conceptId) b
ON b.conceptId = c.ConceptId
LEFT JOIN (SELECT p.conceptId, MAX(p.result.title) AS result FROM study.pregnancy p WHERE p.conceptId IS NOT NULL GROUP BY p.conceptId) po
ON po.conceptId = c.ConceptId
diff --git a/nbri_ehr/resources/queries/study/arrival.js b/nbri_ehr/resources/queries/study/arrival.js
index 251c651..2010ffd 100644
--- a/nbri_ehr/resources/queries/study/arrival.js
+++ b/nbri_ehr/resources/queries/study/arrival.js
@@ -40,7 +40,6 @@ EHR.Server.TriggerManager.registerHandlerForQuery(EHR.Server.TriggerManager.Even
row.birth = row['Id/demographics/birth'] || null;
row.gender = row['Id/demographics/gender'] || null;
row.geographic_origin = row['Id/demographics/geographic_origin'] || null;
- row.source = row.sourceFacility || null;
if (row.QCStateLabel) {
row.qcstate = helper.getJavaHelper().getQCStateForLabel(row.QCStateLabel).getRowId();
diff --git a/nbri_ehr/resources/queries/study/arrival.query.xml b/nbri_ehr/resources/queries/study/arrival.query.xml
index ffe2108..0955496 100644
--- a/nbri_ehr/resources/queries/study/arrival.query.xml
+++ b/nbri_ehr/resources/queries/study/arrival.query.xml
@@ -66,7 +66,8 @@
ehr_lookupssource
- meaning
+ code
+ meaning
diff --git a/nbri_ehr/resources/queries/study/birth.js b/nbri_ehr/resources/queries/study/birth.js
index e3e5fd0..cd0cce1 100644
--- a/nbri_ehr/resources/queries/study/birth.js
+++ b/nbri_ehr/resources/queries/study/birth.js
@@ -38,7 +38,7 @@ EHR.Server.TriggerManager.registerHandlerForQuery(EHR.Server.TriggerManager.Even
//when updating a record that already carries this conception id, the existing row accounts for one match
var conceptIdThreshold = (oldRow && oldRow.conceptId === row.conceptId) ? 1 : 0;
if (triggerHelper.totalRecords('study', 'birth', 'conceptId', row.conceptId) > conceptIdThreshold) {
- EHR.Server.Utils.addError(scriptErrors, 'conceptId', 'This conception Id is already used by another birth record', 'INFO');
+ EHR.Server.Utils.addError(scriptErrors, 'conceptId', 'This conception Id is already used by another birth record', 'WARN');
}
if (triggerHelper.totalRecords('study', 'pregnancy', 'conceptId', row.conceptId) > 0) {
diff --git a/nbri_ehr/resources/queries/study/birth.query.xml b/nbri_ehr/resources/queries/study/birth.query.xml
index 8eccc34..18a5a92 100644
--- a/nbri_ehr/resources/queries/study/birth.query.xml
+++ b/nbri_ehr/resources/queries/study/birth.query.xml
@@ -8,11 +8,18 @@
-
-
+ Birth Date
+
+ Conception Id
+
+ nbri_ehr
+ Conception
+ ConceptId
+
+ Birth Location80
@@ -25,6 +32,25 @@
cage
+
+ Delivery Mode
+ false
+
+ ehr_lookups
+ delivery_mode
+ value
+ title
+
+
+
+ Birth Condition
+
+ ehr_lookups
+ birth_condition
+ value
+ title
+
+ Project
@@ -43,12 +69,13 @@
title
-
- Conception Id
+
+ Breeding Type
- nbri_ehr
- Conception
- ConceptId
+ ehr_lookups
+ breeding_type
+ value
+ title
diff --git a/nbri_ehr/resources/queries/study/demographics.query.xml b/nbri_ehr/resources/queries/study/demographics.query.xml
index bff3d17..f6fafa6 100644
--- a/nbri_ehr/resources/queries/study/demographics.query.xml
+++ b/nbri_ehr/resources/queries/study/demographics.query.xml
@@ -99,9 +99,6 @@
meaning
-
- Source
- CITES
diff --git a/nbri_ehr/resources/queries/study/demographics/.qview.xml b/nbri_ehr/resources/queries/study/demographics/.qview.xml
index 56f1f23..439cd0a 100644
--- a/nbri_ehr/resources/queries/study/demographics/.qview.xml
+++ b/nbri_ehr/resources/queries/study/demographics/.qview.xml
@@ -12,7 +12,6 @@
-
diff --git a/nbri_ehr/resources/queries/study/demographicsSource.sql b/nbri_ehr/resources/queries/study/demographicsSource.sql
index 9de9dfd..6ee341e 100644
--- a/nbri_ehr/resources/queries/study/demographicsSource.sql
+++ b/nbri_ehr/resources/queries/study/demographicsSource.sql
@@ -17,7 +17,7 @@ SELECT
WHEN T1.EarliestArrival IS NULL AND d.birth IS NOT NULL THEN true
ELSE false
END as fromCenter,
- d.source as source,
+ T2.sourceFacility as source,
CASE
WHEN T1.EarliestArrival IS NULL AND d.birth IS NOT NULL THEN 'Born at NBRI'
diff --git a/nbri_ehr/resources/queries/study/departure.query.xml b/nbri_ehr/resources/queries/study/departure.query.xml
index 19845d1..5955592 100644
--- a/nbri_ehr/resources/queries/study/departure.query.xml
+++ b/nbri_ehr/resources/queries/study/departure.query.xml
@@ -13,7 +13,8 @@
ehr_lookupssource
- meaning
+ code
+ meaning
diff --git a/nbri_ehr/resources/queries/study/protocolAssignment.query.xml b/nbri_ehr/resources/queries/study/protocolAssignment.query.xml
index ac61d1c..d95eb07 100644
--- a/nbri_ehr/resources/queries/study/protocolAssignment.query.xml
+++ b/nbri_ehr/resources/queries/study/protocolAssignment.query.xml
@@ -15,7 +15,6 @@
ehrprotocolprotocol
- title
diff --git a/nbri_ehr/resources/referenceStudy/study/datasets/datasets_metadata.xml b/nbri_ehr/resources/referenceStudy/study/datasets/datasets_metadata.xml
index 55e48ea..42317f7 100644
--- a/nbri_ehr/resources/referenceStudy/study/datasets/datasets_metadata.xml
+++ b/nbri_ehr/resources/referenceStudy/study/datasets/datasets_metadata.xml
@@ -224,6 +224,15 @@
varchar
+
+ varchar
+
+
+ varchar
+
+
+ varchar
+
@@ -469,9 +478,6 @@
varchar
-
- varchar
- varchar
diff --git a/nbri_ehr/resources/schemas/dbscripts/postgresql/nbri_ehr-26.000-26.001.sql b/nbri_ehr/resources/schemas/dbscripts/postgresql/nbri_ehr-26.000-26.001.sql
index 964b91c..866fefc 100644
--- a/nbri_ehr/resources/schemas/dbscripts/postgresql/nbri_ehr-26.000-26.001.sql
+++ b/nbri_ehr/resources/schemas/dbscripts/postgresql/nbri_ehr-26.000-26.001.sql
@@ -9,6 +9,7 @@ CREATE TABLE nbri_ehr.Conception
ConceptId VARCHAR(100),
ConceptDate TIMESTAMP,
ConceptTermDate TIMESTAMP,
+ Estimated BOOLEAN DEFAULT FALSE,
Remark TEXT,
Dam VARCHAR(100),
Sire VARCHAR(100),
diff --git a/nbri_ehr/resources/schemas/nbri_ehr.xml b/nbri_ehr/resources/schemas/nbri_ehr.xml
index 6d076c8..2bc125d 100644
--- a/nbri_ehr/resources/schemas/nbri_ehr.xml
+++ b/nbri_ehr/resources/schemas/nbri_ehr.xml
@@ -581,6 +581,7 @@
Date
+
diff --git a/nbri_ehr/resources/scripts/nbri_triggers.js b/nbri_ehr/resources/scripts/nbri_triggers.js
index e4ad95b..190f656 100644
--- a/nbri_ehr/resources/scripts/nbri_triggers.js
+++ b/nbri_ehr/resources/scripts/nbri_triggers.js
@@ -40,9 +40,15 @@ exports.init = function (EHR) {
});
});
+ // the arrival and birth forms assign animals that do not have a demographics record yet, so those forms ask for Id validation to be relaxed
+ function isAllowAnyIdRequested(helper) {
+ helper.decodeExtraContextProperty('allowAnyId', false);
+ return helper.getProperty('allowAnyId') === true; // this can be true or an empty object
+ }
+
EHR.Server.TriggerManager.registerHandlerForQuery(EHR.Server.TriggerManager.Events.INIT, 'study', 'protocolAssignment', function(event, helper) {
helper.setScriptOptions({
- allowAnyId: false,
+ allowAnyId: isAllowAnyIdRequested(helper),
requiresStatusRecalc: false,
allowDatesInDistantPast: true
});
@@ -50,7 +56,7 @@ exports.init = function (EHR) {
EHR.Server.TriggerManager.registerHandlerForQuery(EHR.Server.TriggerManager.Events.INIT, 'study', 'assignment', function(event, helper) {
helper.setScriptOptions({
- allowAnyId: false,
+ allowAnyId: isAllowAnyIdRequested(helper),
requiresStatusRecalc: false,
allowDatesInDistantPast: true,
skipAssignmentCheck: true,
diff --git a/nbri_ehr/resources/web/nbri_ehr/model/sources/Arrival.js b/nbri_ehr/resources/web/nbri_ehr/model/sources/Arrival.js
index 3e2850b..a5e983f 100644
--- a/nbri_ehr/resources/web/nbri_ehr/model/sources/Arrival.js
+++ b/nbri_ehr/resources/web/nbri_ehr/model/sources/Arrival.js
@@ -25,7 +25,7 @@ EHR.model.DataModelManager.registerMetadata('Arrival', {
byQuery: {
'study.arrival': {
'cage': {
- allowBlank: false,
+ // allowBlank: false,
columnConfig: {
fixed: true,
width: 200
@@ -39,45 +39,28 @@ EHR.model.DataModelManager.registerMetadata('Arrival', {
allowBlank: false
},
'Id/demographics/birth': {
- allowBlank: false
+ // allowBlank: false
},
'Id/demographics/gender': {
allowBlank: false
},
'Id/demographics/geographic_origin': {
- allowBlank: false,
+ // allowBlank: false,
columnConfig: {
fixed: true,
width: 200
}
},
+ // project and protocol are entered through the Project Assignment and Protocol Assignment sections
project: {
- xtype: 'combo',
- columnConfig: {
- width: 150
- },
- lookup: {
- schemaName: 'ehr',
- queryName: 'project',
- keyColumn: 'project',
- columns: 'project,name',
- filterArray: [
- LABKEY.Filter.create('isActive', true, LABKEY.Filter.Types.EQUAL),
- ]
- },
- allowBlank: false
+ allowBlank: true,
+ hidden: true,
+ showInGrid: false
},
arrivalProtocol: {
- allowBlank: false,
- columnConfig: {
- width: 200
- },
- lookup: {
- schemaName: 'ehr',
- queryName: 'activeProtocols',
- keyColumn: 'protocol',
- columns: 'protocol,title'
- },
+ allowBlank: true,
+ hidden: true,
+ showInGrid: false
},
performedby: {
hidden: true,
@@ -91,14 +74,14 @@ EHR.model.DataModelManager.registerMetadata('Arrival', {
},
},
acquisitionType: {
- allowBlank: false,
+ // allowBlank: false,
columnConfig: {
fixed: true,
width: 150
},
},
arrivalType: {
- allowBlank: false,
+ // allowBlank: false,
columnConfig: {
width: 200
}
diff --git a/nbri_ehr/resources/web/nbri_ehr/model/sources/Assignment.js b/nbri_ehr/resources/web/nbri_ehr/model/sources/Assignment.js
index 4db08ad..4d38d3c 100644
--- a/nbri_ehr/resources/web/nbri_ehr/model/sources/Assignment.js
+++ b/nbri_ehr/resources/web/nbri_ehr/model/sources/Assignment.js
@@ -37,12 +37,14 @@ EHR.model.DataModelManager.registerMetadata('Assignment', {
fixed: true,
width: 150
},
+ // set displayColumn: ehr.protocol's title column (displayName) is not returned by this query
lookup: {
schemaName: 'ehr',
queryName: 'activeProtocols',
keyColumn: 'protocol',
+ displayColumn: 'protocol',
columns: 'protocol,title'
- },
+ }
}
}
}
diff --git a/nbri_ehr/resources/web/nbri_ehr/model/sources/Birth.js b/nbri_ehr/resources/web/nbri_ehr/model/sources/Birth.js
index 7202b23..f266f1e 100644
--- a/nbri_ehr/resources/web/nbri_ehr/model/sources/Birth.js
+++ b/nbri_ehr/resources/web/nbri_ehr/model/sources/Birth.js
@@ -24,58 +24,68 @@ EHR.model.DataModelManager.registerMetadata('Birth', {
},
byQuery: {
'study.birth': {
+ Id: {
+ allowBlank: false,
+ nullable: false
+ },
+ date: {
+ allowBlank: false,
+ nullable: false
+ },
'Id/demographics/species': {
allowBlank: false,
+ nullable: false,
columnConfig: {
fixed: true,
width: 250
}
},
'cage': {
- allowBlank: false,
+ // allowBlank: false,
columnConfig: {
fixed: true,
width: 200
},
},
- project: {
- xtype: 'combo',
- allowBlank: false,
+ type: {
columnConfig: {
- width: 150
+ width: 200
},
- lookup: {
- schemaName: 'ehr',
- queryName: 'project',
- keyColumn: 'project',
- columns: 'project,name',
- filterArray: [
- LABKEY.Filter.create('isActive', true, LABKEY.Filter.Types.EQUAL),
- ]
- }
},
- birthProtocol: {
+ cond: {
columnConfig: {
width: 200
},
- allowBlank: false,
- lookup: {
- schemaName: 'ehr',
- queryName: 'activeProtocols',
- keyColumn: 'protocol',
- columns: 'protocol,title'
- },
+ },
+ // project and protocol are entered through the Project Assignment and Protocol Assignment sections
+ project: {
+ allowBlank: true,
+ hidden: true,
+ showInGrid: false
+ },
+ birthProtocol: {
+ allowBlank: true,
+ hidden: true,
+ showInGrid: false
},
'Id/demographics/birth': {
allowBlank: false
},
'Id/demographics/gender': {
- allowBlank: false
+ allowBlank: false,
+ nullable: false
},
conceptId: {
+ allowBlank: false,
+ nullable: false,
columnConfig: {
width: 150
}
+ },
+ breedingType: {
+ columnConfig: {
+ width: 200
+ }
}
}
}
diff --git a/nbri_ehr/resources/web/nbri_ehr/model/sources/Conception.js b/nbri_ehr/resources/web/nbri_ehr/model/sources/Conception.js
index d862181..949d8cb 100644
--- a/nbri_ehr/resources/web/nbri_ehr/model/sources/Conception.js
+++ b/nbri_ehr/resources/web/nbri_ehr/model/sources/Conception.js
@@ -35,6 +35,13 @@ EHR.model.DataModelManager.registerMetadata('Conception', {
width: 200
},
},
+ Estimated: {
+ xtype: 'checkbox',
+ defaultValue: false,
+ columnConfig: {
+ width: 100
+ },
+ },
Dam: {
xtype: 'ehr-animalfield',
lookups: false,
diff --git a/nbri_ehr/resources/web/nbri_ehr/window/StartWithConceptionWindow.js b/nbri_ehr/resources/web/nbri_ehr/window/StartWithConceptionWindow.js
new file mode 100644
index 0000000..4c2bb0f
--- /dev/null
+++ b/nbri_ehr/resources/web/nbri_ehr/window/StartWithConceptionWindow.js
@@ -0,0 +1,137 @@
+/*
+ * Copyright (c) 2026 LabKey Corporation
+ *
+ * Licensed under the Apache License, Version 2.0: http://www.apache.org/licenses/LICENSE-2.0
+ */
+
+/**
+ * Adds a birth record pre-populated from an existing conception record.
+ *
+ * @cfg {Object} targetStore
+ * @cfg {Object} formConfig
+ */
+Ext4.define('NBRI_EHR.window.StartWithConceptionWindow', {
+ extend: 'Ext.window.Window',
+
+ initComponent: function(){
+ Ext4.apply(this, {
+ title: 'Start with Conception',
+ modal: true,
+ closeAction: 'destroy',
+ border: true,
+ bodyStyle: 'padding: 5px',
+ width: 400,
+ defaults: {
+ border: false,
+ width: 370
+ },
+ items: [{
+ html: 'Select a conception record. A new birth record will be added using the conception Id, along with the dam, sire and species from that conception.',
+ style: 'padding-bottom: 10px;'
+ },{
+ xtype: 'labkey-combo',
+ itemId: 'conceptionField',
+ fieldLabel: 'Conception Id',
+ displayField: 'ConceptId',
+ valueField: 'ConceptId',
+ forceSelection: true,
+ queryMode: 'local',
+ anyMatch: true,
+ caseSensitive: false,
+ store: {
+ type: 'labkey-store',
+ schemaName: 'nbri_ehr',
+ queryName: 'Conception',
+ columns: 'ConceptId,ConceptDate,Dam,Sire',
+ sort: '-ConceptDate',
+ autoLoad: true
+ }
+ }],
+ buttons: [{
+ text: 'Submit',
+ scope: this,
+ handler: this.onSubmit
+ },{
+ text: 'Close',
+ handler: function(btn){
+ btn.up('window').close();
+ }
+ }]
+ });
+
+ this.callParent(arguments);
+ },
+
+ onSubmit: function(btn){
+ var field = this.down('#conceptionField');
+ var conceptId = field.getValue();
+ if (!conceptId){
+ Ext4.Msg.alert('Error', 'Must select a conception Id');
+ return;
+ }
+
+ var record = field.findRecordByValue(conceptId);
+ if (!record){
+ Ext4.Msg.alert('Error', 'Unable to find the conception record for: ' + conceptId);
+ return;
+ }
+
+ var dam = record.get('Dam');
+ var sire = record.get('Sire');
+
+ btn.disable();
+ this.getSpecies(dam, function(species){
+ this.addRow(conceptId, dam, sire, species);
+ btn.enable();
+ this.close();
+ }, this);
+ },
+
+ // the species of the offspring is inferred from the dam of the conception
+ getSpecies: function(dam, callback, scope){
+ if (!dam){
+ callback.call(scope, null);
+ return;
+ }
+
+ LABKEY.Query.selectRows({
+ schemaName: 'study',
+ queryName: 'demographics',
+ columns: 'Id,species',
+ filterArray: [LABKEY.Filter.create('Id', dam, LABKEY.Filter.Types.EQUAL)],
+ scope: this,
+ success: function(results){
+ var species = results.rows && results.rows.length ? results.rows[0].species : null;
+ callback.call(scope, species);
+ },
+ failure: function(error){
+ console.error(error);
+ callback.call(scope, null);
+ }
+ });
+ },
+
+ addRow: function(conceptId, dam, sire, species){
+ this.targetStore.add(this.targetStore.createModel({
+ conceptId: conceptId,
+ 'Id/demographics/dam': dam,
+ 'Id/demographics/sire': sire,
+ 'Id/demographics/species': species
+ }));
+ }
+});
+
+EHR.DataEntryUtils.registerGridButton('NBRI_START_WITH_CONCEPTION', function(config){
+ return Ext4.Object.merge({
+ text: 'Start with Conception',
+ tooltip: EHR.DataEntryUtils.shouldShowTooltips() ? 'Click to add a birth record populated from an existing conception record' : undefined,
+ handler: function(btn){
+ var grid = btn.up('gridpanel');
+
+ Ext4.create('NBRI_EHR.window.StartWithConceptionWindow', {
+ targetStore: grid.store,
+ formConfig: grid.formConfig
+ }).show();
+ }
+ }, config);
+});
diff --git a/nbri_ehr/src/org/labkey/nbri_ehr/dataentry/form/NBRIArrivalFormType.java b/nbri_ehr/src/org/labkey/nbri_ehr/dataentry/form/NBRIArrivalFormType.java
index b79b90b..61fe238 100644
--- a/nbri_ehr/src/org/labkey/nbri_ehr/dataentry/form/NBRIArrivalFormType.java
+++ b/nbri_ehr/src/org/labkey/nbri_ehr/dataentry/form/NBRIArrivalFormType.java
@@ -23,6 +23,8 @@
import org.labkey.nbri_ehr.dataentry.section.NBRIAnimalDetailsFormSection;
import org.labkey.nbri_ehr.dataentry.section.NBRIArrivalFormSection;
import org.labkey.nbri_ehr.dataentry.section.NBRIArrivalInstructionsFormSection;
+import org.labkey.nbri_ehr.dataentry.section.NBRIProjectAssignmentFormSection;
+import org.labkey.nbri_ehr.dataentry.section.NBRIProtocolAssignmentFormSection;
import org.labkey.nbri_ehr.dataentry.section.NBRITaskFormSection;
import org.labkey.nbri_ehr.dataentry.section.NBRIWeightFormSection;
@@ -40,13 +42,17 @@ public NBRIArrivalFormType(DataEntryFormContext ctx, Module owner)
new NBRITaskFormSection(),
new NBRIAnimalDetailsFormSection(),
new NBRIArrivalFormSection(),
+ new NBRIProtocolAssignmentFormSection(true, true, true),
+ new NBRIProjectAssignmentFormSection(true, true, true),
new NBRIWeightFormSection(true, true)
));
+ addClientDependency(ClientDependency.supplierFromPath("nbri_ehr/model/sources/Assignment.js"));
addClientDependency(ClientDependency.supplierFromPath("nbri_ehr/model/sources/Arrival.js"));
for (FormSection s : getFormSections())
{
+ s.addConfigSource("Assignment");
s.addConfigSource("Arrival");
}
diff --git a/nbri_ehr/src/org/labkey/nbri_ehr/dataentry/form/NBRIBirthFormType.java b/nbri_ehr/src/org/labkey/nbri_ehr/dataentry/form/NBRIBirthFormType.java
index ebe9c2b..cbd66ea 100644
--- a/nbri_ehr/src/org/labkey/nbri_ehr/dataentry/form/NBRIBirthFormType.java
+++ b/nbri_ehr/src/org/labkey/nbri_ehr/dataentry/form/NBRIBirthFormType.java
@@ -24,6 +24,8 @@
import org.labkey.nbri_ehr.dataentry.section.NBRIAnimalDetailsFormSection;
import org.labkey.nbri_ehr.dataentry.section.NBRIBirthFormSection;
import org.labkey.nbri_ehr.dataentry.section.NBRIBirthInstructionsFormSection;
+import org.labkey.nbri_ehr.dataentry.section.NBRIProjectAssignmentFormSection;
+import org.labkey.nbri_ehr.dataentry.section.NBRIProtocolAssignmentFormSection;
import org.labkey.nbri_ehr.dataentry.section.NBRITaskFormSection;
import java.util.ArrayList;
@@ -39,16 +41,20 @@ public NBRIBirthFormType (DataEntryFormContext ctx, Module owner)
new NBRIBirthInstructionsFormSection(),
new NBRITaskFormSection(),
new NBRIAnimalDetailsFormSection(),
- new NBRIBirthFormSection()
+ new NBRIBirthFormSection(),
+ new NBRIProtocolAssignmentFormSection(true, true, true),
+ new NBRIProjectAssignmentFormSection(true, true, true)
));
addClientDependency(ClientDependency.supplierFromPath("nbri_ehr/plugin/RowEditor.js"));
addClientDependency(ClientDependency.supplierFromPath("nbri_ehr/model/sources/NBRIDefault.js"));
+ addClientDependency(ClientDependency.supplierFromPath("nbri_ehr/model/sources/Assignment.js"));
addClientDependency(ClientDependency.supplierFromPath("nbri_ehr/model/sources/Birth.js"));
addClientDependency(ClientDependency.supplierFromPath("nbri_ehr/window/AddAnimalsWindow.js"));
for (FormSection s : getFormSections())
{
+ s.addConfigSource("Assignment");
s.addConfigSource("Birth");
}
}
diff --git a/nbri_ehr/src/org/labkey/nbri_ehr/dataentry/section/NBRIBirthFormSection.java b/nbri_ehr/src/org/labkey/nbri_ehr/dataentry/section/NBRIBirthFormSection.java
index 604cbb9..ddecd53 100644
--- a/nbri_ehr/src/org/labkey/nbri_ehr/dataentry/section/NBRIBirthFormSection.java
+++ b/nbri_ehr/src/org/labkey/nbri_ehr/dataentry/section/NBRIBirthFormSection.java
@@ -22,15 +22,34 @@
import org.labkey.api.query.FieldKey;
import org.labkey.api.view.template.ClientDependency;
+import java.util.ArrayList;
import java.util.List;
public class NBRIBirthFormSection extends NewAnimalFormSection
{
+ // left to right column order of the Births grid; the demographics fields are not on study.birth, so they are added here
+ private static final List COLUMN_ORDER = List.of(
+ FieldKey.fromString("Id"),
+ FieldKey.fromString("date"),
+ FieldKey.fromString("conceptId"),
+ FieldKey.fromString("Id/demographics/species"),
+ FieldKey.fromString("Id/demographics/gender"),
+ FieldKey.fromString("Id/demographics/dam"),
+ FieldKey.fromString("Id/demographics/sire"),
+ FieldKey.fromString("cage"),
+ FieldKey.fromString("type"),
+ FieldKey.fromString("cond"),
+ FieldKey.fromString("breedingType"),
+ FieldKey.fromString("remark"),
+ FieldKey.fromString("performedby")
+ );
+
public NBRIBirthFormSection()
{
super("study", "birth", "Births", false);
addClientDependency(ClientDependency.supplierFromPath("ehr/window/FormBulkAddWindow.js"));
addClientDependency(ClientDependency.supplierFromPath("nbri_ehr/window/FormBulkAddWindow.js"));
+ addClientDependency(ClientDependency.supplierFromPath("nbri_ehr/window/StartWithConceptionWindow.js"));
}
@Override
@@ -46,14 +65,12 @@ public JSONObject toJSON(DataEntryFormContext ctx, boolean includeFormElements)
@Override
protected List getFieldKeys(TableInfo ti)
{
- List keys = super.getFieldKeys(ti);
+ List ordered = new ArrayList<>(COLUMN_ORDER);
- keys.add(2, FieldKey.fromString("Id/demographics/species"));
- keys.add(3, FieldKey.fromString("Id/demographics/gender"));
- keys.add(4, FieldKey.fromString("Id/demographics/dam"));
- keys.add(5, FieldKey.fromString("Id/demographics/sire"));
+ // anything not explicitly ordered above (hidden and system fields) keeps its default position at the end
+ super.getFieldKeys(ti).stream().filter(key -> !COLUMN_ORDER.contains(key)).forEach(ordered::add);
- return keys;
+ return ordered;
}
@Override
@@ -68,6 +85,7 @@ public List getTbarButtons()
defaultButtons.add(idx, "NBRI_ADDANIMALS");
}
defaultButtons.remove("COPYFROMSECTION");
+ defaultButtons.addFirst("NBRI_START_WITH_CONCEPTION");
return defaultButtons;
}
diff --git a/nbri_ehr/src/org/labkey/nbri_ehr/table/NBRI_EHRCustomizer.java b/nbri_ehr/src/org/labkey/nbri_ehr/table/NBRI_EHRCustomizer.java
index 38aa173..38fd24d 100644
--- a/nbri_ehr/src/org/labkey/nbri_ehr/table/NBRI_EHRCustomizer.java
+++ b/nbri_ehr/src/org/labkey/nbri_ehr/table/NBRI_EHRCustomizer.java
@@ -751,7 +751,7 @@ public void doSharedCustomization(AbstractTableInfo ti)
{
UserSchema us = getEHRUserSchema(ti, "ehr_lookups");
col.setLabel("Species");
- col.setFk(new QueryForeignKey(ti.getUserSchema(), ti.getContainerFilter(), us, null, "species_codes", "code", "scientific_name"));
+ col.setFk(new QueryForeignKey(ti.getUserSchema(), ti.getContainerFilter(), us, null, "species_codes", "code", "common_name"));
}
if ("protocol".equalsIgnoreCase(col.getName()) && null == col.getFk() && !"protocol".equalsIgnoreCase(ti.getName()))
{
diff --git a/nbri_ehr/test/src/org.labkey.test/tests.nbri_ehr/NBRI_EHRTest.java b/nbri_ehr/test/src/org.labkey.test/tests.nbri_ehr/NBRI_EHRTest.java
index c7587ae..93eb777 100644
--- a/nbri_ehr/test/src/org.labkey.test/tests.nbri_ehr/NBRI_EHRTest.java
+++ b/nbri_ehr/test/src/org.labkey.test/tests.nbri_ehr/NBRI_EHRTest.java
@@ -363,13 +363,13 @@ private void addNBRIEhrLinks()
@Override
protected String getMale()
{
- return "3";
+ return "M";
}
@Override
protected String getFemale()
{
- return "2";
+ return "F";
}
@Test
@@ -576,13 +576,24 @@ public void testArrivalForm()
arrivals.setGridCell(1, "acquisitionType", "Lab Transfer (Wild Born)");
arrivals.setGridCell(1, "Id", arrivedAnimal);
arrivals.setGridCell(1, "cage", "C1");
- arrivals.setGridCell(1, "project", "640991");
- arrivals.setGridCell(1, "arrivalProtocol", "dummyprotocol");
- arrivals.setGridCell(1, "Id/demographics/gender", "female");
+ arrivals.setGridCell(1, "Id/demographics/gender", "Female");
arrivals.setGridCell(1, "Id/demographics/geographic_origin", "BRAZIL");
- arrivals.setGridCell(1, "Id/demographics/species", "Macaca nemestrina PIG");
+ arrivals.setGridCell(1, "Id/demographics/species", "Pig-Tailed Macaque");
arrivals.setGridCellJS(1, "Id/demographics/birth", now.minusDays(7).format(DateTimeFormatter.ofPattern(DATE_TIME_FORMAT_STRING)));
- arrivals.setGridCell(1, "sourceFacility", "BIOQUAL, Inc.");
+ arrivals.setGridCell(1, "sourceFacility", "BIOQUAL, INCORPORATED");
+
+ Ext4GridRef protocolAssignments = _helper.getExt4GridForFormSection("Protocol Assignment");
+ _helper.addRecordToGrid(protocolAssignments);
+ protocolAssignments.setGridCell(1, "Id", arrivedAnimal);
+ protocolAssignments.setGridCellJS(1, "date", now.minusDays(1).format(DateTimeFormatter.ofPattern(DATE_TIME_FORMAT_STRING)));
+ protocolAssignments.setGridCell(1, "protocol", "dummyprotocol");
+
+ Ext4GridRef projectAssignments = _helper.getExt4GridForFormSection("Project Assignment");
+ _helper.addRecordToGrid(projectAssignments);
+ projectAssignments.setGridCell(1, "Id", arrivedAnimal);
+ projectAssignments.setGridCellJS(1, "date", now.minusDays(1).format(DateTimeFormatter.ofPattern(DATE_TIME_FORMAT_STRING)));
+ projectAssignments.setGridCell(1, "project", "640991");
+
submitForm("Submit Final", "Finalize");
goToSchemaBrowser();
@@ -590,13 +601,19 @@ public void testArrivalForm()
table.setFilter("Id", "Equals", arrivedAnimal);
CustomizeView view = table.openCustomizeGrid();
view.addColumn("cage");
- view.addColumn("project");
- view.addColumn("arrivalProtocol");
view.applyCustomView();
Assert.assertEquals("Invalid Arrival record", Arrays.asList(arrivedAnimal), table.getRowDataAsText(0, "Id"));
Assert.assertEquals("Invalid Arrival record", Arrays.asList("C1"), table.getRowDataAsText(0, "cage"));
- Assert.assertEquals("Invalid Arrival record", Arrays.asList("640991"), table.getRowDataAsText(0, "project"));
- Assert.assertEquals("Invalid Arrival record", Arrays.asList("dummyprotocol"), table.getRowDataAsText(0, "arrivalProtocol"));
+
+ goToSchemaBrowser();
+ table = viewQueryData("study", "assignment");
+ table.setFilter("Id", "Equals", arrivedAnimal);
+ Assert.assertEquals("Invalid project assignment", Arrays.asList("640991"), table.getRowDataAsText(0, "project"));
+
+ goToSchemaBrowser();
+ table = viewQueryData("study", "protocolAssignment");
+ table.setFilter("Id", "Equals", arrivedAnimal);
+ Assert.assertEquals("Invalid protocol assignment", Arrays.asList("dummyprotocol"), table.getRowDataAsText(0, "protocol"));
verifyRowCreated("study", "birth", arrivedAnimal, 1);
verifyRowCreated("study", "assignment", arrivedAnimal, 1);
@@ -606,15 +623,24 @@ public void testArrivalForm()
}
@Test
- public void testBirthForm() throws IOException, CommandException
+ public void testBirthForm() throws Exception
{
String bornAnimal = "80801";
+ String damId = "TESTDAM01";
+ String sireId = "TESTSIRE01";
+ // demographics.species holds an ehr_lookups.species_codes code; the grids display its common name
+ String damSpeciesCode = "CAP";
+ String damSpecies = "Brown-Tufted Capuchin";
String conceptId = "TESTCONCEPT1";
+ String breedingType = "Time-Mated";
LocalDateTime now = LocalDateTime.now();
+ log("Creating the dam and sire of the conception");
+ createBreedingPair(damId, sireId, damSpeciesCode);
+
log("Creating conception record");
InsertRowsCommand conception = new InsertRowsCommand("nbri_ehr", "Conception");
- conception.addRow(Map.of("ConceptId", conceptId, "ConceptDate", now.minusDays(160), "Dam", "TEST4551032"));
+ conception.addRow(Map.of("ConceptId", conceptId, "ConceptDate", now.minusDays(160), "Dam", damId, "Sire", sireId));
conception.execute(getApiHelper().getConnection(), getContainerPath());
gotoEnterData();
@@ -622,15 +648,47 @@ public void testBirthForm() throws IOException, CommandException
lockForm();
Ext4GridRef births = _helper.getExt4GridForFormSection("Births");
- _helper.addRecordToGrid(births);
+ verifyBirthColumnOrder(births);
+
+ log("Starting a birth record from the conception");
+ births.clickTbarButton("Start with Conception");
+ Window> conceptionWindow = new Window.WindowFinder(getDriver()).withTitle("Start with Conception").waitFor();
+ Ext4ComboRef conceptionCombo = _ext4Helper.queryOne("window #conceptionField", Ext4ComboRef.class);
+ Assert.assertNotNull("Conception Id field not found in the Start with Conception window", conceptionCombo);
+ conceptionCombo.waitForStoreLoad();
+ conceptionCombo.setComboByDisplayValue(conceptId);
+ conceptionWindow.clickButton("Submit", 0);
+ births.waitForRowCount(1);
+
+ log("Verifying the conception populated the new birth record");
+ assertEquals("Conception Id was not copied from the conception", conceptId, births.getFieldValue(1, "conceptId"));
+ assertEquals("Dam was not copied from the conception", damId, births.getFieldValue(1, "Id/demographics/dam"));
+ assertEquals("Sire was not copied from the conception", sireId, births.getFieldValue(1, "Id/demographics/sire"));
+ assertEquals("Species was not copied from the dam of the conception", damSpeciesCode, births.getFieldValue(1, "Id/demographics/species"));
+
+ log("Verifying Conception Id is required");
+ births.setGridCellJS(1, "conceptId", null);
+ waitForFormError("The field: Conception Id is required");
+ births.setGridCellJS(1, "conceptId", conceptId);
+
births.setGridCellJS(1, "date", now.minusDays(1).format(DateTimeFormatter.ofPattern(DATE_TIME_FORMAT_STRING)));
births.setGridCell(1, "Id", bornAnimal);
births.setGridCell(1, "cage", "C3");
- births.setGridCell(1, "Id/demographics/species", "Cebus apella CAP");
- births.setGridCell(1, "Id/demographics/gender", "female");
- births.setGridCell(1, "project", "795644");
- births.setGridCell(1, "birthProtocol", "protocol101");
- births.setGridCell(1, "conceptId", conceptId);
+ births.setGridCell(1, "Id/demographics/gender", "Female");
+ births.setGridCell(1, "breedingType", breedingType);
+
+ Ext4GridRef protocolAssignments = _helper.getExt4GridForFormSection("Protocol Assignment");
+ _helper.addRecordToGrid(protocolAssignments);
+ protocolAssignments.setGridCell(1, "Id", bornAnimal);
+ protocolAssignments.setGridCellJS(1, "date", now.minusDays(1).format(DateTimeFormatter.ofPattern(DATE_TIME_FORMAT_STRING)));
+ protocolAssignments.setGridCell(1, "protocol", "protocol101");
+
+ Ext4GridRef projectAssignments = _helper.getExt4GridForFormSection("Project Assignment");
+ _helper.addRecordToGrid(projectAssignments);
+ projectAssignments.setGridCell(1, "Id", bornAnimal);
+ projectAssignments.setGridCellJS(1, "date", now.minusDays(1).format(DateTimeFormatter.ofPattern(DATE_TIME_FORMAT_STRING)));
+ projectAssignments.setGridCell(1, "project", "795644");
+
submitForm("Submit Final", "Finalize");
goToSchemaBrowser();
@@ -638,20 +696,39 @@ public void testBirthForm() throws IOException, CommandException
table.setFilter("Id", "Equals", bornAnimal);
Assert.assertEquals("Invalid Birth record", Arrays.asList(bornAnimal), table.getRowDataAsText(0, "Id"));
Assert.assertEquals("Invalid Birth record", Arrays.asList("C3"), table.getRowDataAsText(0, "cage"));
- Assert.assertEquals("Invalid Birth record", Arrays.asList("795644"), table.getRowDataAsText(0, "project"));
- Assert.assertEquals("Invalid Birth record", Arrays.asList("protocol101"), table.getRowDataAsText(0, "birthProtocol"));
Assert.assertEquals("Invalid Birth record", Arrays.asList(conceptId), table.getRowDataAsText(0, "conceptId"));
+ Assert.assertEquals("Invalid Birth record", Arrays.asList(breedingType), table.getRowDataAsText(0, "breedingType"));
+
+ log("Verifying the dam and sire of the conception reached demographics");
+ goToSchemaBrowser();
+ table = viewQueryData("study", "demographics");
+ table.setFilter("Id", "Equals", bornAnimal);
+ Assert.assertEquals("Invalid demographics record", Arrays.asList(damId), table.getRowDataAsText(0, "dam"));
+ Assert.assertEquals("Invalid demographics record", Arrays.asList(sireId), table.getRowDataAsText(0, "sire"));
+ Assert.assertEquals("Invalid demographics record", Arrays.asList(damSpecies), table.getRowDataAsText(0, "species"));
+
+ goToSchemaBrowser();
+ table = viewQueryData("study", "assignment");
+ table.setFilter("Id", "Equals", bornAnimal);
+ Assert.assertEquals("Invalid project assignment", Arrays.asList("795644"), table.getRowDataAsText(0, "project"));
+
+ goToSchemaBrowser();
+ table = viewQueryData("study", "protocolAssignment");
+ table.setFilter("Id", "Equals", bornAnimal);
+ Assert.assertEquals("Invalid protocol assignment", Arrays.asList("protocol101"), table.getRowDataAsText(0, "protocol"));
verifyRowCreated("study", "assignment", bornAnimal, 1);
verifyRowCreated("study", "protocolAssignment", bornAnimal, 1);
verifyRowCreated("study", "housing", bornAnimal, 1);
verifyRowCreated("study", "demographics", bornAnimal, 1);
- log("Verifying conception outcome in ConceptionsByDam");
+ log("Verifying conception outcome and offspring in ConceptionsByDam");
goToSchemaBrowser();
DataRegionTable report = viewQueryData("nbri_ehr", "ConceptionsByDam");
report.setFilter("ConceptId", "Equals", conceptId);
+ Assert.assertEquals("Invalid ConceptionsByDam row", Arrays.asList(damId), report.getRowDataAsText(0, "Id"));
Assert.assertEquals("Invalid ConceptionsByDam row", Arrays.asList("Live Birth"), report.getRowDataAsText(0, "conceptionOutcome"));
+ Assert.assertEquals("Invalid ConceptionsByDam row", Arrays.asList(bornAnimal), report.getRowDataAsText(0, "offspring"));
}
@Test
@@ -706,13 +783,20 @@ public void testConceptionForm()
lockForm();
Ext4GridRef conceptions = _helper.getExt4GridForFormSection("Conception");
+ Assert.assertFalse("Breeding Type describes the birth and should no longer appear on the Conception form",
+ conceptions.isColumnPresent("breedingType", false));
+
_helper.addRecordToGrid(conceptions);
conceptions.setGridCell(1, "ConceptId", conceptId);
conceptions.setGridCellJS(1, "ConceptDate", now.minusDays(30).format(_dateFormat));
conceptions.setGridCellJS(1, "ConceptTermDate", now.plusDays(135).format(_dateFormat));
+ conceptions.setGridCellJS(1, "Estimated", true);
conceptions.setGridCell(1, "Dam", damId);
conceptions.setGridCell(1, "Sire", sireId);
- conceptions.setGridCell(1, "Remark", "Conception entry test");
+ // Remark renders as a textarea, which Ext4GridRef's cell editor helpers cannot drive: they only recognize
+ // an as the active editor, so the click that opens the textarea is followed by a retry click that
+ // the open textarea intercepts. Set it through the store instead.
+ conceptions.setGridCellJS(1, "Remark", "Conception entry test");
submitForm("Submit Final", "Finalize");
goToSchemaBrowser();
@@ -720,6 +804,7 @@ public void testConceptionForm()
table.setFilter("ConceptId", "Equals", conceptId);
Assert.assertEquals("Invalid Conception record", Arrays.asList(damId), table.getRowDataAsText(0, "Dam"));
Assert.assertEquals("Invalid Conception record", Arrays.asList(sireId), table.getRowDataAsText(0, "Sire"));
+ Assert.assertEquals("Invalid Conception record", Arrays.asList("true"), table.getRowDataAsText(0, "Estimated"));
Assert.assertEquals("Invalid Conception record", Arrays.asList("Conception entry test"), table.getRowDataAsText(0, "Remark"));
log("Verifying unmatched conception appears as Unknown in ConceptionsByDam");
@@ -1615,6 +1700,44 @@ private int countLines(File file) throws Exception
}
}
+ // Creates the parents of a conception. They need a species from the ehr_lookups.species list because the
+ // Start with Conception window copies the dam's species onto the newborn, and the reference study's
+ // demographics data carries placeholder species values that no lookup entry matches.
+ private void createBreedingPair(String damId, String sireId, String species) throws Exception
+ {
+ String[] fields = new String[]{"Id", "Species", "Birth", "Gender", "date", "calculated_status", "objectid", "performedby"};
+ Object[][] data = new Object[][]{
+ {damId, species, (new Date()).toString(), getFemale(), new Date(), "Alive", UUID.randomUUID().toString(), 1004},
+ {sireId, species, (new Date()).toString(), getMale(), new Date(), "Alive", UUID.randomUUID().toString(), 1004}
+ };
+ SimplePostCommand insertCommand = getApiHelper().prepareInsertCommand("study", "demographics", "lsid", fields, data);
+ getApiHelper().deleteAllRecords("study", "demographics", new Filter("Id", damId + ";" + sireId, Filter.Operator.IN));
+ getApiHelper().doSaveRows(DATA_ADMIN.getEmail(), insertCommand, getExtraContext());
+ }
+
+ // Asserts the Births columns appear in the expected left to right order. Relative position is checked rather
+ // than absolute index so that hidden and system columns can come and go without breaking the test.
+ private void verifyBirthColumnOrder(Ext4GridRef births)
+ {
+ List expectedOrder = List.of("Id", "date", "conceptId", "Id/demographics/species", "Id/demographics/gender",
+ "Id/demographics/dam", "Id/demographics/sire", "cage", "type", "cond", "breedingType", "remark", "performedby");
+
+ int previousIdx = 0;
+ String previousCol = null;
+ for (String col : expectedOrder)
+ {
+ int idx = births.getIndexOfColumn(col, true);
+ Assert.assertTrue("Births column '" + col + "' should appear to the right of '" + previousCol + "'", idx > previousIdx);
+ previousIdx = idx;
+ previousCol = col;
+ }
+ }
+
+ private void waitForFormError(String message)
+ {
+ waitFor(() -> isTextPresent(message), "Form did not report: " + message, WAIT_FOR_JAVASCRIPT);
+ }
+
private void verifyRowCreated(String schema, String query, String animalId, int rowCount)
{
goToSchemaBrowser();