From 1f95c4aa18277e8a44144640ead2f82614231fa8 Mon Sep 17 00:00:00 2001 From: ayobi Date: Wed, 2 Oct 2024 18:42:45 -0400 Subject: [PATCH 01/12] init commit --- microsetta_private_api/admin/admin_impl.py | 20 +- .../admin/sample_summary.py | 42 +++- .../api/microsetta_private_api.yaml | 16 ++ microsetta_private_api/repo/admin_repo.py | 196 ++++++++++++++++++ microsetta_private_api/repo/kit_repo.py | 15 ++ 5 files changed, 285 insertions(+), 4 deletions(-) diff --git a/microsetta_private_api/admin/admin_impl.py b/microsetta_private_api/admin/admin_impl.py index b52975852..2bba7eefd 100644 --- a/microsetta_private_api/admin/admin_impl.py +++ b/microsetta_private_api/admin/admin_impl.py @@ -29,7 +29,9 @@ post_daklapack_orders from microsetta_private_api import localization from microsetta_private_api.admin.sample_summary import per_sample -from microsetta_private_api.admin.sample_summary import get_barcodes_for +from microsetta_private_api.admin.sample_summary import get_barcodes_by_project_id,\ + get_barcodes_by_kit_ids, get_barcodes_by_emails,\ + get_barcodes_by_outbound_tracking_numbers, get_barcodes_by_inbound_tracking_numbers from microsetta_private_api.util.melissa import verify_address from microsetta_private_api.util.query_builder_to_sql import build_condition from werkzeug.exceptions import Unauthorized @@ -500,12 +502,26 @@ def query_project_barcode_stats(body, token_info, strip_sampleid): def query_barcode_stats(body, token_info, strip_sampleid): validate_admin_access(token_info) + print("body", body) if 'sample_barcodes' in body: project_id = None barcodes = body["sample_barcodes"] + elif 'kit_ids' in body: + project_id = None + barcodes = get_barcodes_by_kit_ids(body["kit_ids"]) + print("kit id barcodes", barcodes) + elif 'emails' in body: + project_id = None + barcodes = get_barcodes_by_emails(body["emails"]) + elif 'outbound_tracking_numbers' in body: + project_id = None + barcodes = get_barcodes_by_outbound_tracking_numbers(body["outbound_tracking_numbers"]) + elif 'inbound_tracking_numbers' in body: + project_id = None + barcodes = get_barcodes_by_inbound_tracking_numbers(body["inbound_tracking_numbers"]) elif 'project_id' in body: project_id = body["project_id"] - barcodes = get_barcodes_for(project_id) + barcodes = get_barcodes_by_project_id(project_id) unprocessed_barcodes = None diff --git a/microsetta_private_api/admin/sample_summary.py b/microsetta_private_api/admin/sample_summary.py index a64f00e2a..dd6f7b2ae 100644 --- a/microsetta_private_api/admin/sample_summary.py +++ b/microsetta_private_api/admin/sample_summary.py @@ -1,4 +1,5 @@ from microsetta_private_api.model.source import Source +from microsetta_private_api.repo.kit_repo import KitRepo from microsetta_private_api.repo.sample_repo import SampleRepo from microsetta_private_api.repo.transaction import Transaction from microsetta_private_api.repo.admin_repo import AdminRepo @@ -7,12 +8,40 @@ from werkzeug.exceptions import NotFound -def get_barcodes_for(project_id): +def get_barcodes_by_project_id(project_id): if project_id is None: raise ValueError("project_id must be defined.") with Transaction() as t: return AdminRepo(t).get_project_barcodes(project_id) + +def get_barcodes_by_kit_ids(kit_ids): + if kit_ids is None: + raise ValueError("kit_id must be defined.") + + with Transaction() as t: + return AdminRepo(t).get_kit_barcodes(kit_ids) + +def get_barcodes_by_emails(emails): + if emails is None: + raise ValueError("email must be defined.") + + with Transaction() as t: + return AdminRepo(t).get_email_barcodes(emails) + +def get_barcodes_by_outbound_tracking_numbers(outbound_tracking_numbers): + if outbound_tracking_numbers is None: + raise ValueError("outbound_tracking_numbers must be defined.") + + with Transaction() as t: + return AdminRepo(t).get_outbound_tracking_barcodes(outbound_tracking_numbers) + +def get_barcodes_by_inbound_tracking_numbers(inbound_tracking_numbers): + if inbound_tracking_numbers is None: + raise ValueError("inbound_tracking_numbers must be defined.") + + with Transaction() as t: + return AdminRepo(t).get_inbound_tracking_barcodes(inbound_tracking_numbers) def per_sample(project, barcodes, strip_sampleid): @@ -21,6 +50,7 @@ def per_sample(project, barcodes, strip_sampleid): admin_repo = AdminRepo(t) sample_repo = SampleRepo(t) template_repo = SurveyTemplateRepo(t) + kit_repo = KitRepo(t) vs_repo = VioscreenSessionRepo(t) # all associated projects returned for each barcode, @@ -83,6 +113,10 @@ def per_sample(project, barcodes, strip_sampleid): ffq_complete, ffq_taken, _ = vs_repo.get_ffq_status_by_sample( sample.id ) + + kit_id_name = kit_repo.get_kit_id_name_by_barcode(barcode) + outbound_fedex_tracking = admin_repo.get_outbound_tracking_by_barcodes(barcode) + inbound_fedex_tracking = admin_repo.get_inbound_tracking_by_barcodes(barcode) summary = { "sampleid": None if strip_sampleid else barcode, @@ -96,7 +130,11 @@ def per_sample(project, barcodes, strip_sampleid): "ffq-taken": ffq_taken, "ffq-complete": ffq_complete, "sample-status": sample_status, - "sample-received": sample_status is not None + "sample-received": sample_status is not None, + "kit-id": kit_id_name, + "outbound-tracking": outbound_fedex_tracking, + "inbound-tracking": inbound_fedex_tracking + } for status in ["sample-is-valid", diff --git a/microsetta_private_api/api/microsetta_private_api.yaml b/microsetta_private_api/api/microsetta_private_api.yaml index 88c96e8dc..ac3b36ea2 100644 --- a/microsetta_private_api/api/microsetta_private_api.yaml +++ b/microsetta_private_api/api/microsetta_private_api.yaml @@ -2998,6 +2998,22 @@ paths: # not using the defined schema for sample_barcode as it is # readOnly type: string + 'kit_ids': + type: array + items: + type: string + 'emails': + type: array + items: + type: string + 'outbound_tracking_numbers': + type: array + items: + type: string + 'inbound_tracking_numbers': + type: array + items: + type: string responses: '200': description: Return an object containing a list of dictionaries of sample status for requested accounts diff --git a/microsetta_private_api/repo/admin_repo.py b/microsetta_private_api/repo/admin_repo.py index 5770c5433..8d4167870 100644 --- a/microsetta_private_api/repo/admin_repo.py +++ b/microsetta_private_api/repo/admin_repo.py @@ -555,6 +555,202 @@ def get_project_barcodes(self, project_id): else: cur.execute(query, [project_id, ]) return list([v[0] for v in cur.fetchall()]) + + def get_kit_barcodes(self, kit_ids): + """Obtain the barcodes associated with a kit + + Parameters + ---------- + kit_ids : list + The list of kit IDs to obtain barcodes for + + Returns + ------- + list + The list of observed barcodes + """ + query_kit_ids = """ + SELECT ag_kit_id + FROM ag.ag_kit + WHERE supplied_kit_id IN %s + """ + + with self._transaction.cursor() as cur: + cur.execute(query_kit_ids, [tuple(kit_ids)]) + ag_kit_ids = [row[0] for row in cur.fetchall()] + + if not ag_kit_ids: + return [] + + query_barcodes = """ + SELECT barcode + FROM ag.ag_kit_barcodes + WHERE ag_kit_id IN %s + """ + cur.execute(query_barcodes, [tuple(ag_kit_ids)]) + return [row[0] for row in cur.fetchall()] + + def get_email_barcodes(self, emails): + """Obtain the barcodes associated with an email + + Parameters + ---------- + emails : list + The list of emails to obtain barcodes for + + Returns + ------- + list + The list of observed barcodes + """ + query_emails = """ + SELECT created_with_kit_id + FROM ag.account + WHERE email IN %s + """ + + with self._transaction.cursor() as cur: + cur.execute(query_emails, [tuple(emails)]) + created_with_kit_ids = [row[0] for row in cur.fetchall()] + + if not created_with_kit_ids: + return [] + + query_barcodes = """ + SELECT barcode + FROM barcodes.barcode + WHERE kit_id IN %s + """ + cur.execute(query_barcodes, [tuple(created_with_kit_ids)]) + return [row[0] for row in cur.fetchall()] + + def get_outbound_tracking_barcodes(self, outbound_tracking_numbers): + """Obtain the barcodes associated with an outbound tracking number + + Parameters + ---------- + outbound_tracking_numbers : list + The list of outbound tracking numbers to obtain barcodes for + + Returns + ------- + list + The list of observed barcodes + """ + query_outbound_tracking = """ + SELECT kit_id + FROM barcodes.kit + WHERE outbound_fedex_tracking IN %s + """ + + with self._transaction.cursor() as cur: + cur.execute(query_outbound_tracking, [tuple(outbound_tracking_numbers)]) + kit_ids = [row[0] for row in cur.fetchall()] + + if not kit_ids: + return [] + + query_barcodes = """ + SELECT barcode + FROM barcodes.barcode + WHERE kit_id IN %s + """ + cur.execute(query_barcodes, [tuple(kit_ids)]) + return [row[0] for row in cur.fetchall()] + + def get_inbound_tracking_barcodes(self, inbound_tracking_numbers): + """Obtain the barcodes associated with an inbound tracking number + + Parameters + ---------- + inbound_tracking_numbers : list + The list of inbound tracking numbers to obtain barcodes for + + Returns + ------- + list + The list of observed barcodes + """ + query_inbound_tracking = """ + SELECT kit_id + FROM barcodes.kit + WHERE inbound_fedex_tracking IN %s + """ + + with self._transaction.cursor() as cur: + cur.execute(query_inbound_tracking, [tuple(inbound_tracking_numbers)]) + kit_ids = [row[0] for row in cur.fetchall()] + + if not kit_ids: + return [] + + query_barcodes = """ + SELECT barcode + FROM barcodes.barcode + WHERE kit_id IN %s + """ + cur.execute(query_barcodes, [tuple(kit_ids)]) + return [row[0] for row in cur.fetchall()] + + def get_outbound_tracking_by_barcodes(self, barcodes): + """Obtain the outbound tracking numbers associated with a barcode + + Parameters + ---------- + barcodes : list + The list of barcodes to obtain outbound tracking numbers for + + Returns + ------- + list + The list of observed outbound tracking numbers + """ + query = """ + SELECT k.outbound_fedex_tracking + FROM barcodes.barcode b + JOIN barcodes.kit k ON b.kit_id = k.kit_id + WHERE b.barcode IN %s + """ + + with self._transaction.cursor() as cur: + cur.execute(query, [tuple(barcodes)]) + + rows = cur.fetchall() + + if len(rows) == 0: + return None + + return [row[0] for row in rows] + + def get_inbound_tracking_by_barcodes(self, barcodes): + """Obtain the inbound tracking numbers associated with a barcode + + Parameters + ---------- + barcodes : list + The list of barcodes to obtain inbound tracking numbers for + + Returns + ------- + list + The list of observed inbound tracking numbers + """ + query = """ + SELECT k.inbound_fedex_tracking + FROM barcodes.barcode b + JOIN barcodes.kit k ON b.kit_id = k.kit_id + WHERE b.barcode IN %s + """ + + with self._transaction.cursor() as cur: + cur.execute(query, [tuple(barcodes)]) + + rows = cur.fetchall() + + if len(rows) == 0: + return None + + return [row[0] for row in rows] def create_project(self, project): """Create a project entry in the database diff --git a/microsetta_private_api/repo/kit_repo.py b/microsetta_private_api/repo/kit_repo.py index ce3491442..0d1cba426 100644 --- a/microsetta_private_api/repo/kit_repo.py +++ b/microsetta_private_api/repo/kit_repo.py @@ -67,3 +67,18 @@ def get_kit_unused_samples(self, supplied_kit_id): else: samples = [sample_repo._get_sample_by_id(r[1]) for r in rows] return Kit(rows[0][0], samples) + + def get_kit_id_name_by_barcode(self, barcode): + with self._transaction.cursor() as cur: + cur.execute(""" + SELECT kit_id + FROM barcodes.barcode + WHERE barcode = %s + """, (barcode,)) + + rows = cur.fetchall() + + if len(rows) == 0: + return None + else: + return rows[0][0] From 5b0c77fa1d582e8e63ec8d6327dc13dd08bdb22c Mon Sep 17 00:00:00 2001 From: ayobi Date: Wed, 2 Oct 2024 22:29:52 -0400 Subject: [PATCH 02/12] added queries for sample summary table --- microsetta_private_api/admin/admin_impl.py | 12 ++- .../admin/sample_summary.py | 35 +++++--- microsetta_private_api/repo/admin_repo.py | 90 +++++++++++++++++-- microsetta_private_api/repo/kit_repo.py | 6 +- 4 files changed, 118 insertions(+), 25 deletions(-) diff --git a/microsetta_private_api/admin/admin_impl.py b/microsetta_private_api/admin/admin_impl.py index 2bba7eefd..d3b8cf876 100644 --- a/microsetta_private_api/admin/admin_impl.py +++ b/microsetta_private_api/admin/admin_impl.py @@ -29,9 +29,11 @@ post_daklapack_orders from microsetta_private_api import localization from microsetta_private_api.admin.sample_summary import per_sample -from microsetta_private_api.admin.sample_summary import get_barcodes_by_project_id,\ +from microsetta_private_api.admin.sample_summary import \ + get_barcodes_by_project_id,\ get_barcodes_by_kit_ids, get_barcodes_by_emails,\ - get_barcodes_by_outbound_tracking_numbers, get_barcodes_by_inbound_tracking_numbers + get_barcodes_by_outbound_tracking_numbers,\ + get_barcodes_by_inbound_tracking_numbers from microsetta_private_api.util.melissa import verify_address from microsetta_private_api.util.query_builder_to_sql import build_condition from werkzeug.exceptions import Unauthorized @@ -515,10 +517,12 @@ def query_barcode_stats(body, token_info, strip_sampleid): barcodes = get_barcodes_by_emails(body["emails"]) elif 'outbound_tracking_numbers' in body: project_id = None - barcodes = get_barcodes_by_outbound_tracking_numbers(body["outbound_tracking_numbers"]) + barcodes = get_barcodes_by_outbound_tracking_numbers + (body["outbound_tracking_numbers"]) elif 'inbound_tracking_numbers' in body: project_id = None - barcodes = get_barcodes_by_inbound_tracking_numbers(body["inbound_tracking_numbers"]) + barcodes = get_barcodes_by_inbound_tracking_numbers + (body["inbound_tracking_numbers"]) elif 'project_id' in body: project_id = body["project_id"] barcodes = get_barcodes_by_project_id(project_id) diff --git a/microsetta_private_api/admin/sample_summary.py b/microsetta_private_api/admin/sample_summary.py index dd6f7b2ae..3e34f6670 100644 --- a/microsetta_private_api/admin/sample_summary.py +++ b/microsetta_private_api/admin/sample_summary.py @@ -14,34 +14,40 @@ def get_barcodes_by_project_id(project_id): with Transaction() as t: return AdminRepo(t).get_project_barcodes(project_id) - + + def get_barcodes_by_kit_ids(kit_ids): if kit_ids is None: raise ValueError("kit_id must be defined.") with Transaction() as t: return AdminRepo(t).get_kit_barcodes(kit_ids) - + + def get_barcodes_by_emails(emails): if emails is None: raise ValueError("email must be defined.") with Transaction() as t: return AdminRepo(t).get_email_barcodes(emails) - + + def get_barcodes_by_outbound_tracking_numbers(outbound_tracking_numbers): if outbound_tracking_numbers is None: raise ValueError("outbound_tracking_numbers must be defined.") with Transaction() as t: - return AdminRepo(t).get_outbound_tracking_barcodes(outbound_tracking_numbers) - + return AdminRepo(t).get_outbound_tracking_barcodes + (outbound_tracking_numbers) + + def get_barcodes_by_inbound_tracking_numbers(inbound_tracking_numbers): if inbound_tracking_numbers is None: raise ValueError("inbound_tracking_numbers must be defined.") with Transaction() as t: - return AdminRepo(t).get_inbound_tracking_barcodes(inbound_tracking_numbers) + return AdminRepo(t).get_inbound_tracking_barcodes + (inbound_tracking_numbers) def per_sample(project, barcodes, strip_sampleid): @@ -113,10 +119,16 @@ def per_sample(project, barcodes, strip_sampleid): ffq_complete, ffq_taken, _ = vs_repo.get_ffq_status_by_sample( sample.id ) - + kit_id_name = kit_repo.get_kit_id_name_by_barcode(barcode) - outbound_fedex_tracking = admin_repo.get_outbound_tracking_by_barcodes(barcode) - inbound_fedex_tracking = admin_repo.get_inbound_tracking_by_barcodes(barcode) + outbound_fedex_tracking = \ + admin_repo.get_outbound_tracking_by_barcodes(barcode) + inbound_fedex_tracking = \ + admin_repo.get_inbound_tracking_by_barcodes(barcode) + first_scan_timestamp_status = \ + admin_repo.get_first_scan_timestamp_by_barcodes(barcode) + last_scan_timestamp_status = \ + admin_repo.get_last_scan_timestamp_by_barcodes(barcode) summary = { "sampleid": None if strip_sampleid else barcode, @@ -133,8 +145,9 @@ def per_sample(project, barcodes, strip_sampleid): "sample-received": sample_status is not None, "kit-id": kit_id_name, "outbound-tracking": outbound_fedex_tracking, - "inbound-tracking": inbound_fedex_tracking - + "inbound-tracking": inbound_fedex_tracking, + "first-scan-timestamp-status": first_scan_timestamp_status, + "last-scan-timestamp-status": last_scan_timestamp_status } for status in ["sample-is-valid", diff --git a/microsetta_private_api/repo/admin_repo.py b/microsetta_private_api/repo/admin_repo.py index 8d4167870..e2be77dcb 100644 --- a/microsetta_private_api/repo/admin_repo.py +++ b/microsetta_private_api/repo/admin_repo.py @@ -555,7 +555,7 @@ def get_project_barcodes(self, project_id): else: cur.execute(query, [project_id, ]) return list([v[0] for v in cur.fetchall()]) - + def get_kit_barcodes(self, kit_ids): """Obtain the barcodes associated with a kit @@ -589,7 +589,7 @@ def get_kit_barcodes(self, kit_ids): """ cur.execute(query_barcodes, [tuple(ag_kit_ids)]) return [row[0] for row in cur.fetchall()] - + def get_email_barcodes(self, emails): """Obtain the barcodes associated with an email @@ -623,7 +623,7 @@ def get_email_barcodes(self, emails): """ cur.execute(query_barcodes, [tuple(created_with_kit_ids)]) return [row[0] for row in cur.fetchall()] - + def get_outbound_tracking_barcodes(self, outbound_tracking_numbers): """Obtain the barcodes associated with an outbound tracking number @@ -644,7 +644,8 @@ def get_outbound_tracking_barcodes(self, outbound_tracking_numbers): """ with self._transaction.cursor() as cur: - cur.execute(query_outbound_tracking, [tuple(outbound_tracking_numbers)]) + cur.execute(query_outbound_tracking, + [tuple(outbound_tracking_numbers)]) kit_ids = [row[0] for row in cur.fetchall()] if not kit_ids: @@ -657,7 +658,7 @@ def get_outbound_tracking_barcodes(self, outbound_tracking_numbers): """ cur.execute(query_barcodes, [tuple(kit_ids)]) return [row[0] for row in cur.fetchall()] - + def get_inbound_tracking_barcodes(self, inbound_tracking_numbers): """Obtain the barcodes associated with an inbound tracking number @@ -678,7 +679,8 @@ def get_inbound_tracking_barcodes(self, inbound_tracking_numbers): """ with self._transaction.cursor() as cur: - cur.execute(query_inbound_tracking, [tuple(inbound_tracking_numbers)]) + cur.execute(query_inbound_tracking, + [tuple(inbound_tracking_numbers)]) kit_ids = [row[0] for row in cur.fetchall()] if not kit_ids: @@ -721,7 +723,7 @@ def get_outbound_tracking_by_barcodes(self, barcodes): return None return [row[0] for row in rows] - + def get_inbound_tracking_by_barcodes(self, barcodes): """Obtain the inbound tracking numbers associated with a barcode @@ -752,6 +754,80 @@ def get_inbound_tracking_by_barcodes(self, barcodes): return [row[0] for row in rows] + def get_first_scan_timestamp_by_barcodes(self, barcodes): + """Obtain the first scan timestamp and + sample status associated with a barcode + + Parameters + ---------- + barcodes : list + The list of barcodes to obtain first + scan timestamps and sample statuses for + + Returns + ------- + list + A list of tuples where each tuple contains + the first scan timestamp and sample status + """ + + if isinstance(barcodes, str): + barcodes = [barcodes] + + query = """ + SELECT MIN(scan_timestamp), sample_status + FROM barcodes.barcode_scans + WHERE barcode = %s + GROUP BY sample_status + ORDER BY MIN(scan_timestamp) + LIMIT 1 + """ + + with self._transaction.cursor() as cur: + for barcode in barcodes: + cur.execute(query, [barcode]) + result = cur.fetchone() + results = result[0], result[1] + + return results + + def get_last_scan_timestamp_by_barcodes(self, barcodes): + """Obtain the last scan timestamp and + sample status associated with a barcode + + Parameters + ---------- + barcodes : list + The list of barcodes to obtain last + scan timestamps and sample statuses for + + Returns + ------- + list + A list of tuples where each tuple contains + the last scan timestamp and sample status + """ + + if isinstance(barcodes, str): + barcodes = [barcodes] + + query = """ + SELECT MAX(scan_timestamp), sample_status + FROM barcodes.barcode_scans + WHERE barcode = %s + GROUP BY sample_status + ORDER BY MAX(scan_timestamp) DESC + LIMIT 1 + """ + + with self._transaction.cursor() as cur: + for barcode in barcodes: + cur.execute(query, [barcode]) + result = cur.fetchone() + results = result[0], result[1] + + return results + def create_project(self, project): """Create a project entry in the database diff --git a/microsetta_private_api/repo/kit_repo.py b/microsetta_private_api/repo/kit_repo.py index 0d1cba426..dad96574d 100644 --- a/microsetta_private_api/repo/kit_repo.py +++ b/microsetta_private_api/repo/kit_repo.py @@ -67,12 +67,12 @@ def get_kit_unused_samples(self, supplied_kit_id): else: samples = [sample_repo._get_sample_by_id(r[1]) for r in rows] return Kit(rows[0][0], samples) - + def get_kit_id_name_by_barcode(self, barcode): with self._transaction.cursor() as cur: cur.execute(""" - SELECT kit_id - FROM barcodes.barcode + SELECT kit_id + FROM barcodes.barcode WHERE barcode = %s """, (barcode,)) From ca736fd6d667723de4ca57b2f613a40163e8d627 Mon Sep 17 00:00:00 2001 From: ayobi Date: Thu, 17 Oct 2024 15:48:27 -0400 Subject: [PATCH 03/12] change email query for sample summary --- microsetta_private_api/admin/admin_impl.py | 10 ++---- .../admin/sample_summary.py | 4 +-- microsetta_private_api/repo/admin_repo.py | 35 ++++++++----------- microsetta_private_api/repo/kit_repo.py | 15 -------- 4 files changed, 18 insertions(+), 46 deletions(-) diff --git a/microsetta_private_api/admin/admin_impl.py b/microsetta_private_api/admin/admin_impl.py index d3b8cf876..65c2da179 100644 --- a/microsetta_private_api/admin/admin_impl.py +++ b/microsetta_private_api/admin/admin_impl.py @@ -504,23 +504,19 @@ def query_project_barcode_stats(body, token_info, strip_sampleid): def query_barcode_stats(body, token_info, strip_sampleid): validate_admin_access(token_info) - print("body", body) + + project_id = None + if 'sample_barcodes' in body: - project_id = None barcodes = body["sample_barcodes"] elif 'kit_ids' in body: - project_id = None barcodes = get_barcodes_by_kit_ids(body["kit_ids"]) - print("kit id barcodes", barcodes) elif 'emails' in body: - project_id = None barcodes = get_barcodes_by_emails(body["emails"]) elif 'outbound_tracking_numbers' in body: - project_id = None barcodes = get_barcodes_by_outbound_tracking_numbers (body["outbound_tracking_numbers"]) elif 'inbound_tracking_numbers' in body: - project_id = None barcodes = get_barcodes_by_inbound_tracking_numbers (body["inbound_tracking_numbers"]) elif 'project_id' in body: diff --git a/microsetta_private_api/admin/sample_summary.py b/microsetta_private_api/admin/sample_summary.py index 3e34f6670..6740f337b 100644 --- a/microsetta_private_api/admin/sample_summary.py +++ b/microsetta_private_api/admin/sample_summary.py @@ -1,5 +1,4 @@ from microsetta_private_api.model.source import Source -from microsetta_private_api.repo.kit_repo import KitRepo from microsetta_private_api.repo.sample_repo import SampleRepo from microsetta_private_api.repo.transaction import Transaction from microsetta_private_api.repo.admin_repo import AdminRepo @@ -56,7 +55,6 @@ def per_sample(project, barcodes, strip_sampleid): admin_repo = AdminRepo(t) sample_repo = SampleRepo(t) template_repo = SurveyTemplateRepo(t) - kit_repo = KitRepo(t) vs_repo = VioscreenSessionRepo(t) # all associated projects returned for each barcode, @@ -120,7 +118,7 @@ def per_sample(project, barcodes, strip_sampleid): sample.id ) - kit_id_name = kit_repo.get_kit_id_name_by_barcode(barcode) + kit_id_name = sample_repo._get_supplied_kit_id_by_sample(barcode) outbound_fedex_tracking = \ admin_repo.get_outbound_tracking_by_barcodes(barcode) inbound_fedex_tracking = \ diff --git a/microsetta_private_api/repo/admin_repo.py b/microsetta_private_api/repo/admin_repo.py index e2be77dcb..bf94dbad2 100644 --- a/microsetta_private_api/repo/admin_repo.py +++ b/microsetta_private_api/repo/admin_repo.py @@ -604,25 +604,17 @@ def get_email_barcodes(self, emails): The list of observed barcodes """ query_emails = """ - SELECT created_with_kit_id - FROM ag.account - WHERE email IN %s + SELECT akb.barcode + FROM ag.source AS s + JOIN ag.ag_kit_barcodes AS akb + ON s.id = akb.source_id + WHERE s.participant_email IN %s """ with self._transaction.cursor() as cur: cur.execute(query_emails, [tuple(emails)]) - created_with_kit_ids = [row[0] for row in cur.fetchall()] - - if not created_with_kit_ids: - return [] - - query_barcodes = """ - SELECT barcode - FROM barcodes.barcode - WHERE kit_id IN %s - """ - cur.execute(query_barcodes, [tuple(created_with_kit_ids)]) - return [row[0] for row in cur.fetchall()] + barcodes = [row[0] for row in cur.fetchall()] + return barcodes def get_outbound_tracking_barcodes(self, outbound_tracking_numbers): """Obtain the barcodes associated with an outbound tracking number @@ -787,9 +779,10 @@ def get_first_scan_timestamp_by_barcodes(self, barcodes): for barcode in barcodes: cur.execute(query, [barcode]) result = cur.fetchone() - results = result[0], result[1] + if result: + results = result[0], result[1] - return results + return results def get_last_scan_timestamp_by_barcodes(self, barcodes): """Obtain the last scan timestamp and @@ -819,14 +812,14 @@ def get_last_scan_timestamp_by_barcodes(self, barcodes): ORDER BY MAX(scan_timestamp) DESC LIMIT 1 """ - + results = [] with self._transaction.cursor() as cur: for barcode in barcodes: cur.execute(query, [barcode]) result = cur.fetchone() - results = result[0], result[1] - - return results + if result: + results.append((result[0], result[1])) + return results def create_project(self, project): """Create a project entry in the database diff --git a/microsetta_private_api/repo/kit_repo.py b/microsetta_private_api/repo/kit_repo.py index dad96574d..ce3491442 100644 --- a/microsetta_private_api/repo/kit_repo.py +++ b/microsetta_private_api/repo/kit_repo.py @@ -67,18 +67,3 @@ def get_kit_unused_samples(self, supplied_kit_id): else: samples = [sample_repo._get_sample_by_id(r[1]) for r in rows] return Kit(rows[0][0], samples) - - def get_kit_id_name_by_barcode(self, barcode): - with self._transaction.cursor() as cur: - cur.execute(""" - SELECT kit_id - FROM barcodes.barcode - WHERE barcode = %s - """, (barcode,)) - - rows = cur.fetchall() - - if len(rows) == 0: - return None - else: - return rows[0][0] From 9bc52f0e9db9b9cec3f2e77d7b1e0eee1da619a9 Mon Sep 17 00:00:00 2001 From: ayobi Date: Mon, 21 Oct 2024 20:10:03 -0300 Subject: [PATCH 04/12] remove value errors for get barcodes --- microsetta_private_api/admin/sample_summary.py | 15 --------------- 1 file changed, 15 deletions(-) diff --git a/microsetta_private_api/admin/sample_summary.py b/microsetta_private_api/admin/sample_summary.py index 6740f337b..5b7ada783 100644 --- a/microsetta_private_api/admin/sample_summary.py +++ b/microsetta_private_api/admin/sample_summary.py @@ -8,42 +8,27 @@ def get_barcodes_by_project_id(project_id): - if project_id is None: - raise ValueError("project_id must be defined.") - with Transaction() as t: return AdminRepo(t).get_project_barcodes(project_id) def get_barcodes_by_kit_ids(kit_ids): - if kit_ids is None: - raise ValueError("kit_id must be defined.") - with Transaction() as t: return AdminRepo(t).get_kit_barcodes(kit_ids) def get_barcodes_by_emails(emails): - if emails is None: - raise ValueError("email must be defined.") - with Transaction() as t: return AdminRepo(t).get_email_barcodes(emails) def get_barcodes_by_outbound_tracking_numbers(outbound_tracking_numbers): - if outbound_tracking_numbers is None: - raise ValueError("outbound_tracking_numbers must be defined.") - with Transaction() as t: return AdminRepo(t).get_outbound_tracking_barcodes (outbound_tracking_numbers) def get_barcodes_by_inbound_tracking_numbers(inbound_tracking_numbers): - if inbound_tracking_numbers is None: - raise ValueError("inbound_tracking_numbers must be defined.") - with Transaction() as t: return AdminRepo(t).get_inbound_tracking_barcodes (inbound_tracking_numbers) From d2acf271522f6b87c97b1c08e342632a51a5b819 Mon Sep 17 00:00:00 2001 From: ayobi Date: Tue, 22 Oct 2024 15:41:47 -0300 Subject: [PATCH 05/12] update sample summaries queries --- .../admin/sample_summary.py | 12 +- microsetta_private_api/repo/admin_repo.py | 147 +++++------------- 2 files changed, 44 insertions(+), 115 deletions(-) diff --git a/microsetta_private_api/admin/sample_summary.py b/microsetta_private_api/admin/sample_summary.py index 5b7ada783..5dbfd8f19 100644 --- a/microsetta_private_api/admin/sample_summary.py +++ b/microsetta_private_api/admin/sample_summary.py @@ -14,24 +14,24 @@ def get_barcodes_by_project_id(project_id): def get_barcodes_by_kit_ids(kit_ids): with Transaction() as t: - return AdminRepo(t).get_kit_barcodes(kit_ids) + return AdminRepo(t).get_barcodes_filter(kit_ids=kit_ids) def get_barcodes_by_emails(emails): with Transaction() as t: - return AdminRepo(t).get_email_barcodes(emails) + return AdminRepo(t).get_barcodes_filter(emails=emails) def get_barcodes_by_outbound_tracking_numbers(outbound_tracking_numbers): with Transaction() as t: - return AdminRepo(t).get_outbound_tracking_barcodes - (outbound_tracking_numbers) + return AdminRepo(t).get_barcodes_filter( + outbound_tracking_numbers=outbound_tracking_numbers) def get_barcodes_by_inbound_tracking_numbers(inbound_tracking_numbers): with Transaction() as t: - return AdminRepo(t).get_inbound_tracking_barcodes - (inbound_tracking_numbers) + return AdminRepo(t).get_barcodes_filter( + inbound_tracking_numbers=inbound_tracking_numbers) def per_sample(project, barcodes, strip_sampleid): diff --git a/microsetta_private_api/repo/admin_repo.py b/microsetta_private_api/repo/admin_repo.py index bf94dbad2..711b11c06 100644 --- a/microsetta_private_api/repo/admin_repo.py +++ b/microsetta_private_api/repo/admin_repo.py @@ -556,135 +556,64 @@ def get_project_barcodes(self, project_id): cur.execute(query, [project_id, ]) return list([v[0] for v in cur.fetchall()]) - def get_kit_barcodes(self, kit_ids): - """Obtain the barcodes associated with a kit + def get_barcodes_filter(self, kit_ids=None, emails=None, + outbound_tracking_numbers=None, + inbound_tracking_numbers=None): + """Obtain the barcodes based on different filtering criteria. Parameters ---------- - kit_ids : list - The list of kit IDs to obtain barcodes for + kit_ids : list, optional + List of kit IDs to obtain barcodes for. + emails : list, optional + List of emails to obtain barcodes for. + outbound_tracking_numbers : list, optional + List of outbound tracking numbers to obtain barcodes for. + inbound_tracking_numbers : list, optional + List of inbound tracking numbers to obtain barcodes for. Returns ------- list - The list of observed barcodes + The list of observed barcodes based on the provided criteria. """ - query_kit_ids = """ - SELECT ag_kit_id - FROM ag.ag_kit - WHERE supplied_kit_id IN %s + query = """ + SELECT b.barcode + FROM barcodes.barcode AS b + JOIN barcodes.kit AS k ON b.kit_id = k.kit_id """ - with self._transaction.cursor() as cur: - cur.execute(query_kit_ids, [tuple(kit_ids)]) - ag_kit_ids = [row[0] for row in cur.fetchall()] + conditions = [] + params = [] - if not ag_kit_ids: - return [] + if kit_ids: + conditions.append("k.kit_id IN %s") + params.append(tuple(kit_ids)) - query_barcodes = """ - SELECT barcode - FROM ag.ag_kit_barcodes - WHERE ag_kit_id IN %s + if emails: + query += """ + JOIN ag.ag_kit_barcodes AS akb ON akb.barcode = b.barcode + JOIN ag.source AS s ON s.id = akb.source_id """ - cur.execute(query_barcodes, [tuple(ag_kit_ids)]) - return [row[0] for row in cur.fetchall()] + conditions.append("s.participant_email IN %s") + params.append(tuple(emails)) - def get_email_barcodes(self, emails): - """Obtain the barcodes associated with an email + if outbound_tracking_numbers: + conditions.append("k.outbound_fedex_tracking IN %s") + params.append(tuple(outbound_tracking_numbers)) - Parameters - ---------- - emails : list - The list of emails to obtain barcodes for + if inbound_tracking_numbers: + conditions.append("k.inbound_fedex_tracking IN %s") + params.append(tuple(inbound_tracking_numbers)) - Returns - ------- - list - The list of observed barcodes - """ - query_emails = """ - SELECT akb.barcode - FROM ag.source AS s - JOIN ag.ag_kit_barcodes AS akb - ON s.id = akb.source_id - WHERE s.participant_email IN %s - """ + if conditions: + query += " WHERE " + " AND ".join(conditions) with self._transaction.cursor() as cur: - cur.execute(query_emails, [tuple(emails)]) + cur.execute(query, params) barcodes = [row[0] for row in cur.fetchall()] - return barcodes - - def get_outbound_tracking_barcodes(self, outbound_tracking_numbers): - """Obtain the barcodes associated with an outbound tracking number - - Parameters - ---------- - outbound_tracking_numbers : list - The list of outbound tracking numbers to obtain barcodes for - - Returns - ------- - list - The list of observed barcodes - """ - query_outbound_tracking = """ - SELECT kit_id - FROM barcodes.kit - WHERE outbound_fedex_tracking IN %s - """ - - with self._transaction.cursor() as cur: - cur.execute(query_outbound_tracking, - [tuple(outbound_tracking_numbers)]) - kit_ids = [row[0] for row in cur.fetchall()] - - if not kit_ids: - return [] - - query_barcodes = """ - SELECT barcode - FROM barcodes.barcode - WHERE kit_id IN %s - """ - cur.execute(query_barcodes, [tuple(kit_ids)]) - return [row[0] for row in cur.fetchall()] - def get_inbound_tracking_barcodes(self, inbound_tracking_numbers): - """Obtain the barcodes associated with an inbound tracking number - - Parameters - ---------- - inbound_tracking_numbers : list - The list of inbound tracking numbers to obtain barcodes for - - Returns - ------- - list - The list of observed barcodes - """ - query_inbound_tracking = """ - SELECT kit_id - FROM barcodes.kit - WHERE inbound_fedex_tracking IN %s - """ - - with self._transaction.cursor() as cur: - cur.execute(query_inbound_tracking, - [tuple(inbound_tracking_numbers)]) - kit_ids = [row[0] for row in cur.fetchall()] - - if not kit_ids: - return [] - - query_barcodes = """ - SELECT barcode - FROM barcodes.barcode - WHERE kit_id IN %s - """ - cur.execute(query_barcodes, [tuple(kit_ids)]) - return [row[0] for row in cur.fetchall()] + return barcodes def get_outbound_tracking_by_barcodes(self, barcodes): """Obtain the outbound tracking numbers associated with a barcode From 63882c0657775b9dab7c58304e3096db40472c5e Mon Sep 17 00:00:00 2001 From: ayobi Date: Tue, 22 Oct 2024 15:51:24 -0300 Subject: [PATCH 06/12] change email query for sample summaries --- microsetta_private_api/repo/admin_repo.py | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/microsetta_private_api/repo/admin_repo.py b/microsetta_private_api/repo/admin_repo.py index 711b11c06..de14b9e62 100644 --- a/microsetta_private_api/repo/admin_repo.py +++ b/microsetta_private_api/repo/admin_repo.py @@ -594,8 +594,9 @@ def get_barcodes_filter(self, kit_ids=None, emails=None, query += """ JOIN ag.ag_kit_barcodes AS akb ON akb.barcode = b.barcode JOIN ag.source AS s ON s.id = akb.source_id + JOIN ag.account AS a ON s.account_id = a.id """ - conditions.append("s.participant_email IN %s") + conditions.append("a.email IN %s") params.append(tuple(emails)) if outbound_tracking_numbers: From 736dcb27d406f07573093f05b744d76e4ee9ad9a Mon Sep 17 00:00:00 2001 From: ayobi Date: Wed, 23 Oct 2024 16:25:28 -0300 Subject: [PATCH 07/12] changes based on feedback, added tests --- .../admin/sample_summary.py | 41 +++-- .../admin/tests/test_admin_repo.py | 134 ++++++++++++++++ microsetta_private_api/repo/admin_repo.py | 144 ++++-------------- 3 files changed, 193 insertions(+), 126 deletions(-) diff --git a/microsetta_private_api/admin/sample_summary.py b/microsetta_private_api/admin/sample_summary.py index 5dbfd8f19..6b9484700 100644 --- a/microsetta_private_api/admin/sample_summary.py +++ b/microsetta_private_api/admin/sample_summary.py @@ -57,6 +57,20 @@ def per_sample(project, barcodes, strip_sampleid): sample = diag['sample'] account = diag['account'] source = diag['source'] + first_scans_info = diag['scans_info'] + last_scans_info = diag['latest_scan'] + if first_scans_info: + first_scan_timestamp = first_scans_info[0]['scan_timestamp'] + first_scan_status = first_scans_info[0]['sample_status'] + else: + first_scan_timestamp = None + first_scan_status = None + if last_scans_info: + latest_scan_timestamp = last_scans_info['scan_timestamp'] + latest_scan_status = last_scans_info['sample_status'] + else: + latest_scan_timestamp = None + latest_scan_status = None account_email = None if account is None else account.email source_type = None if source is None else source.source_type @@ -103,15 +117,18 @@ def per_sample(project, barcodes, strip_sampleid): sample.id ) - kit_id_name = sample_repo._get_supplied_kit_id_by_sample(barcode) - outbound_fedex_tracking = \ - admin_repo.get_outbound_tracking_by_barcodes(barcode) - inbound_fedex_tracking = \ - admin_repo.get_inbound_tracking_by_barcodes(barcode) - first_scan_timestamp_status = \ - admin_repo.get_first_scan_timestamp_by_barcodes(barcode) - last_scan_timestamp_status = \ - admin_repo.get_last_scan_timestamp_by_barcodes(barcode) + kit_by_barcode = admin_repo.get_kit_by_barcode([barcode]) + + if kit_by_barcode and len(kit_by_barcode) > 0: + info = kit_by_barcode[0] + + kit_id_name = info['kit_id'] + outbound_fedex_tracking = info['outbound_tracking'] + inbound_fedex_tracking = info['inbound_tracking'] + else: + kit_id_name = None + outbound_fedex_tracking = None + inbound_fedex_tracking = None summary = { "sampleid": None if strip_sampleid else barcode, @@ -126,11 +143,13 @@ def per_sample(project, barcodes, strip_sampleid): "ffq-complete": ffq_complete, "sample-status": sample_status, "sample-received": sample_status is not None, + "first-scan-timestamp": first_scan_timestamp, + "first-scan-status": first_scan_status, + "latest-scan-timestamp": latest_scan_timestamp, + "latest-scan-status": latest_scan_status, "kit-id": kit_id_name, "outbound-tracking": outbound_fedex_tracking, "inbound-tracking": inbound_fedex_tracking, - "first-scan-timestamp-status": first_scan_timestamp_status, - "last-scan-timestamp-status": last_scan_timestamp_status } for status in ["sample-is-valid", diff --git a/microsetta_private_api/admin/tests/test_admin_repo.py b/microsetta_private_api/admin/tests/test_admin_repo.py index 40da36a7a..89f5b7bb3 100644 --- a/microsetta_private_api/admin/tests/test_admin_repo.py +++ b/microsetta_private_api/admin/tests/test_admin_repo.py @@ -1487,3 +1487,137 @@ def test_update_perk_fulfillment_state(self): ) obs = cur.fetchone() self.assertFalse(obs[0]) + + def test_get_barcodes_filter_kit_ids_success(self): + with Transaction() as t: + setup_sql = """ + INSERT INTO barcodes.kit (kit_id, box_id) + VALUES ('test1', '0001e15f-4170-4b28-b111-191cd567c347'); + + INSERT INTO barcodes.barcode (barcode, kit_id) + VALUES ('00001234', 'test1'); + """ + with t.cursor() as cur: + cur.execute(setup_sql) + + admin_repo = AdminRepo(t) + + barcodes = admin_repo.get_barcodes_filter(kit_ids=['test1']) + self.assertEqual(barcodes, ['00001234']) + + def test_get_barcodes_filter_kit_ids_failure(self): + with Transaction() as t: + admin_repo = AdminRepo(t) + barcodes = admin_repo.get_barcodes_filter(kit_ids=['notarealkit']) + self.assertEqual(barcodes, []) + + def test_get_barcodes_filter_emails_success(self): + with Transaction() as t: + setup_sql = """ + INSERT INTO ag.source (id, account_id, + source_type, source_name) + VALUES ('0003ddfd-4949-4105-90a9-1b1530af5352', %s, + 'Human', 'Test Source'); + INSERT INTO barcodes.kit (kit_id, box_id) + VALUES ('test1', '0001e15f-4170-4b28-b111-191cd567c347'); + INSERT INTO barcodes.barcode (barcode, kit_id) + VALUES ('00001234', 'test1'); + INSERT INTO ag.ag_kit_barcodes (barcode, source_id) + VALUES ('00001234', '0003ddfd-4949-4105-90a9-1b1530af5352'); + """ + with t.cursor() as cur: + cur.execute(setup_sql, (STANDARD_ACCT_ID,)) + + admin_repo = AdminRepo(t) + + barcodes = admin_repo.get_barcodes_filter(emails=['foo@baz.com']) + self.assertEqual(barcodes, ['00001234']) + + def test_get_barcodes_filter_emails_failure(self): + with Transaction() as t: + admin_repo = AdminRepo(t) + barcodes = admin_repo.get_barcodes_filter( + emails=['notarealemail@example.com']) + self.assertEqual(barcodes, []) + + def test_get_barcodes_filter_outbound_tracking_success(self): + with Transaction() as t: + setup_sql = """ + INSERT INTO barcodes.kit (kit_id, box_id, + outbound_fedex_tracking) + VALUES ('test1', '0001e15f-4170-4b28-b111-191cd567c347', + '12345'); + INSERT INTO barcodes.barcode (barcode, kit_id) + VALUES ('00001234', 'test1'); + """ + with t.cursor() as cur: + cur.execute(setup_sql) + + admin_repo = AdminRepo(t) + + barcodes = \ + admin_repo.get_barcodes_filter( + outbound_tracking_numbers=['12345']) + self.assertEqual(barcodes, ['00001234']) + + def test_get_barcodes_filter_outbound_tracking_failure(self): + with Transaction() as t: + admin_repo = AdminRepo(t) + barcodes = admin_repo.get_barcodes_filter( + outbound_tracking_numbers=['99999']) + self.assertEqual(barcodes, []) + + def test_get_barcodes_filter_inbound_tracking_success(self): + with Transaction() as t: + setup_sql = """ + INSERT INTO barcodes.kit (kit_id, box_id, + inbound_fedex_tracking) + VALUES ('test1', '0001e15f-4170-4b28-b111-191cd567c347', + '67890'); + INSERT INTO barcodes.barcode (barcode, kit_id) + VALUES ('00001234', 'test1'); + """ + with t.cursor() as cur: + cur.execute(setup_sql) + + admin_repo = AdminRepo(t) + + barcodes = admin_repo.get_barcodes_filter( + inbound_tracking_numbers=['67890']) + self.assertEqual(barcodes, ['00001234']) + + def test_get_barcodes_filter_inbound_tracking_failure(self): + with Transaction() as t: + admin_repo = AdminRepo(t) + barcodes = admin_repo.get_barcodes_filter( + inbound_tracking_numbers=['99999']) + self.assertEqual(barcodes, []) + + def test_get_kit_by_barcode_success(self): + with Transaction() as t: + setup_sql = """ + INSERT INTO barcodes.kit (kit_id, box_id) + VALUES ('test1', '0001e15f-4170-4b28-b111-191cd567c348'); + + INSERT INTO barcodes.barcode (barcode, kit_id) + VALUES ('00001234', 'test1'); + """ + with t.cursor() as cur: + cur.execute(setup_sql) + + admin_repo = AdminRepo(t) + + kit_info = admin_repo.get_kit_by_barcode(['00001234']) + expected = [{ + 'barcode': '00001234', + 'outbound_tracking': None, + 'inbound_tracking': None, + 'kit_id': 'test1' + }] + self.assertEqual(kit_info, expected) + + def test_get_kit_by_barcode_failure(self): + with Transaction() as t: + admin_repo = AdminRepo(t) + kit_info = admin_repo.get_kit_by_barcode(['nonexistent_barcode']) + self.assertIsNone(kit_info) diff --git a/microsetta_private_api/repo/admin_repo.py b/microsetta_private_api/repo/admin_repo.py index de14b9e62..163dfa70f 100644 --- a/microsetta_private_api/repo/admin_repo.py +++ b/microsetta_private_api/repo/admin_repo.py @@ -616,24 +616,35 @@ def get_barcodes_filter(self, kit_ids=None, emails=None, return barcodes - def get_outbound_tracking_by_barcodes(self, barcodes): - """Obtain the outbound tracking numbers associated with a barcode + def get_kit_by_barcode(self, barcodes): + """Obtain the outbound tracking, inbound tracking numbers, + and kit ID associated with a list of barcodes. Parameters ---------- barcodes : list - The list of barcodes to obtain outbound tracking numbers for + The list of barcodes to obtain information for. Returns ------- - list - The list of observed outbound tracking numbers + list of dict + A list of dictionaries with outbound tracking, + inbound tracking, and kit ID for each barcode. """ query = """ - SELECT k.outbound_fedex_tracking - FROM barcodes.barcode b - JOIN barcodes.kit k ON b.kit_id = k.kit_id - WHERE b.barcode IN %s + SELECT + b.barcode, + k.outbound_fedex_tracking, + k.inbound_fedex_tracking, + k.kit_id + FROM + barcodes.barcode b + JOIN + barcodes.kit k + ON + b.kit_id = k.kit_id + WHERE + b.barcode IN %s """ with self._transaction.cursor() as cur: @@ -644,112 +655,15 @@ def get_outbound_tracking_by_barcodes(self, barcodes): if len(rows) == 0: return None - return [row[0] for row in rows] - - def get_inbound_tracking_by_barcodes(self, barcodes): - """Obtain the inbound tracking numbers associated with a barcode - - Parameters - ---------- - barcodes : list - The list of barcodes to obtain inbound tracking numbers for - - Returns - ------- - list - The list of observed inbound tracking numbers - """ - query = """ - SELECT k.inbound_fedex_tracking - FROM barcodes.barcode b - JOIN barcodes.kit k ON b.kit_id = k.kit_id - WHERE b.barcode IN %s - """ - - with self._transaction.cursor() as cur: - cur.execute(query, [tuple(barcodes)]) - - rows = cur.fetchall() - - if len(rows) == 0: - return None - - return [row[0] for row in rows] - - def get_first_scan_timestamp_by_barcodes(self, barcodes): - """Obtain the first scan timestamp and - sample status associated with a barcode - - Parameters - ---------- - barcodes : list - The list of barcodes to obtain first - scan timestamps and sample statuses for - - Returns - ------- - list - A list of tuples where each tuple contains - the first scan timestamp and sample status - """ - - if isinstance(barcodes, str): - barcodes = [barcodes] - - query = """ - SELECT MIN(scan_timestamp), sample_status - FROM barcodes.barcode_scans - WHERE barcode = %s - GROUP BY sample_status - ORDER BY MIN(scan_timestamp) - LIMIT 1 - """ - - with self._transaction.cursor() as cur: - for barcode in barcodes: - cur.execute(query, [barcode]) - result = cur.fetchone() - if result: - results = result[0], result[1] - - return results - - def get_last_scan_timestamp_by_barcodes(self, barcodes): - """Obtain the last scan timestamp and - sample status associated with a barcode - - Parameters - ---------- - barcodes : list - The list of barcodes to obtain last - scan timestamps and sample statuses for - - Returns - ------- - list - A list of tuples where each tuple contains - the last scan timestamp and sample status - """ - - if isinstance(barcodes, str): - barcodes = [barcodes] - - query = """ - SELECT MAX(scan_timestamp), sample_status - FROM barcodes.barcode_scans - WHERE barcode = %s - GROUP BY sample_status - ORDER BY MAX(scan_timestamp) DESC - LIMIT 1 - """ - results = [] - with self._transaction.cursor() as cur: - for barcode in barcodes: - cur.execute(query, [barcode]) - result = cur.fetchone() - if result: - results.append((result[0], result[1])) - return results + return [ + { + "barcode": row[0], + "outbound_tracking": row[1], + "inbound_tracking": row[2], + "kit_id": row[3] + } + for row in rows + ] def create_project(self, project): """Create a project entry in the database From 31f1097095dbef80753a1cf8db9b0a25be09ae75 Mon Sep 17 00:00:00 2001 From: ayobi Date: Thu, 24 Oct 2024 17:24:51 -0300 Subject: [PATCH 08/12] resolve ffq conflict --- microsetta_private_api/admin/sample_summary.py | 6 ------ 1 file changed, 6 deletions(-) diff --git a/microsetta_private_api/admin/sample_summary.py b/microsetta_private_api/admin/sample_summary.py index 6b9484700..69673ee81 100644 --- a/microsetta_private_api/admin/sample_summary.py +++ b/microsetta_private_api/admin/sample_summary.py @@ -3,7 +3,6 @@ from microsetta_private_api.repo.transaction import Transaction from microsetta_private_api.repo.admin_repo import AdminRepo from microsetta_private_api.repo.survey_template_repo import SurveyTemplateRepo -from microsetta_private_api.repo.vioscreen_repo import VioscreenSessionRepo from werkzeug.exceptions import NotFound @@ -40,7 +39,6 @@ def per_sample(project, barcodes, strip_sampleid): admin_repo = AdminRepo(t) sample_repo = SampleRepo(t) template_repo = SurveyTemplateRepo(t) - vs_repo = VioscreenSessionRepo(t) # all associated projects returned for each barcode, # so no universal project needed @@ -113,10 +111,6 @@ def per_sample(project, barcodes, strip_sampleid): sample_date = None sample_time = None - ffq_complete, ffq_taken, _ = vs_repo.get_ffq_status_by_sample( - sample.id - ) - kit_by_barcode = admin_repo.get_kit_by_barcode([barcode]) if kit_by_barcode and len(kit_by_barcode) > 0: From 73810986975c00eb0e62774b2b9f36b7c68164ea Mon Sep 17 00:00:00 2001 From: ayobi Date: Thu, 24 Oct 2024 17:29:16 -0300 Subject: [PATCH 09/12] fix vs_repo --- microsetta_private_api/admin/sample_summary.py | 2 ++ 1 file changed, 2 insertions(+) diff --git a/microsetta_private_api/admin/sample_summary.py b/microsetta_private_api/admin/sample_summary.py index 42630cf28..55e296983 100644 --- a/microsetta_private_api/admin/sample_summary.py +++ b/microsetta_private_api/admin/sample_summary.py @@ -3,6 +3,7 @@ from microsetta_private_api.repo.transaction import Transaction from microsetta_private_api.repo.admin_repo import AdminRepo from microsetta_private_api.repo.survey_template_repo import SurveyTemplateRepo +from microsetta_private_api.repo.vioscreen_repo import VioscreenRepo from werkzeug.exceptions import NotFound @@ -39,6 +40,7 @@ def per_sample(project, barcodes, strip_sampleid): admin_repo = AdminRepo(t) sample_repo = SampleRepo(t) template_repo = SurveyTemplateRepo(t) + vs_repo = VioscreenRepo() # all associated projects returned for each barcode, # so no universal project needed From 70cf54bba2e2f262d11d7940337ccdd9f7849478 Mon Sep 17 00:00:00 2001 From: ayobi Date: Thu, 24 Oct 2024 17:37:52 -0300 Subject: [PATCH 10/12] forgot t for transaction --- microsetta_private_api/admin/sample_summary.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/microsetta_private_api/admin/sample_summary.py b/microsetta_private_api/admin/sample_summary.py index 55e296983..ae1d04f08 100644 --- a/microsetta_private_api/admin/sample_summary.py +++ b/microsetta_private_api/admin/sample_summary.py @@ -40,7 +40,7 @@ def per_sample(project, barcodes, strip_sampleid): admin_repo = AdminRepo(t) sample_repo = SampleRepo(t) template_repo = SurveyTemplateRepo(t) - vs_repo = VioscreenRepo() + vs_repo = VioscreenRepo(t) # all associated projects returned for each barcode, # so no universal project needed From 610509bf333b38ba28c0c41c18cb92eb3ada5878 Mon Sep 17 00:00:00 2001 From: ayobi Date: Thu, 24 Oct 2024 18:13:31 -0300 Subject: [PATCH 11/12] fixed wrong import --- microsetta_private_api/admin/sample_summary.py | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/microsetta_private_api/admin/sample_summary.py b/microsetta_private_api/admin/sample_summary.py index ae1d04f08..4c22bcb57 100644 --- a/microsetta_private_api/admin/sample_summary.py +++ b/microsetta_private_api/admin/sample_summary.py @@ -3,7 +3,7 @@ from microsetta_private_api.repo.transaction import Transaction from microsetta_private_api.repo.admin_repo import AdminRepo from microsetta_private_api.repo.survey_template_repo import SurveyTemplateRepo -from microsetta_private_api.repo.vioscreen_repo import VioscreenRepo +from microsetta_private_api.repo.vioscreen_repo import VioscreenSessionRepo from werkzeug.exceptions import NotFound @@ -40,7 +40,7 @@ def per_sample(project, barcodes, strip_sampleid): admin_repo = AdminRepo(t) sample_repo = SampleRepo(t) template_repo = SurveyTemplateRepo(t) - vs_repo = VioscreenRepo(t) + vs_repo = VioscreenSessionRepo(t) # all associated projects returned for each barcode, # so no universal project needed From 812bbaea253e2480c2a51c73e32bd778ee810de2 Mon Sep 17 00:00:00 2001 From: ayobi Date: Mon, 28 Oct 2024 16:04:16 -0300 Subject: [PATCH 12/12] fix in/outbound search --- microsetta_private_api/admin/admin_impl.py | 10 ++++++---- 1 file changed, 6 insertions(+), 4 deletions(-) diff --git a/microsetta_private_api/admin/admin_impl.py b/microsetta_private_api/admin/admin_impl.py index 65c2da179..46af6143c 100644 --- a/microsetta_private_api/admin/admin_impl.py +++ b/microsetta_private_api/admin/admin_impl.py @@ -514,11 +514,13 @@ def query_barcode_stats(body, token_info, strip_sampleid): elif 'emails' in body: barcodes = get_barcodes_by_emails(body["emails"]) elif 'outbound_tracking_numbers' in body: - barcodes = get_barcodes_by_outbound_tracking_numbers - (body["outbound_tracking_numbers"]) + barcodes = get_barcodes_by_outbound_tracking_numbers( + body["outbound_tracking_numbers"] + ) elif 'inbound_tracking_numbers' in body: - barcodes = get_barcodes_by_inbound_tracking_numbers - (body["inbound_tracking_numbers"]) + barcodes = get_barcodes_by_inbound_tracking_numbers( + body["inbound_tracking_numbers"] + ) elif 'project_id' in body: project_id = body["project_id"] barcodes = get_barcodes_by_project_id(project_id)