diff --git a/microsetta_private_api/admin/admin_impl.py b/microsetta_private_api/admin/admin_impl.py index 2bba7eef..d3b8cf87 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 dd6f7b2a..3e34f667 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 8d416787..e2be77dc 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 0d1cba42..dad96574 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,))