Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Adds Withdrawn Note based on TSV location columns #726

Merged
merged 1 commit into from
Aug 3, 2023
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
33 changes: 31 additions & 2 deletions libsys_airflow/plugins/folio/items.py
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,9 @@
logger = logging.getLogger(__name__)

# TODO: once on python >= 3.11, can mark "codes" specifically as NotRequired; for now, total=False makes all keys optional
BarcodeDict = TypedDict('BarcodeDict', {"suppress?": bool, "codes": list}, total=False)
BarcodeDict = TypedDict(
'BarcodeDict', {"suppress?": bool, "codes": list, "withdrawn?": bool}, total=False
)


def _determine_discovery_suppress(row: dict, suppressed_locations: dict) -> bool:
Expand Down Expand Up @@ -47,6 +49,15 @@ def _determine_stat_codes(row: dict, stat_codes: dict) -> list:
return codes


def _determine_withdrawn(row: dict) -> bool:
"""
Determines if Item is withdrawn
"""
return row["HOMELOCATION"].startswith("WITHDRAWN") or row[
"CURRENTLOCATION"
].startswith("WITHDRAWN")


def _generate_item_notes(
item, tsv_note_df: pd.DataFrame, item_note_types: dict
) -> None:
Expand Down Expand Up @@ -124,6 +135,9 @@ def _generate_items_lookups(
if len(codes) > 0:
items_lookup[row["BARCODE"]]["codes"] = codes

# Withdrawn
items_lookup[row["BARCODE"]]["withdrawn?"] = _determine_withdrawn(row)

return items_lookup


Expand Down Expand Up @@ -195,6 +209,20 @@ def _retrieve_item_notes_ids(folio_client) -> dict:
return note_types


def _set_withdrawn_note(item: dict, item_lookups: dict, note_types: dict) -> None:
"""
Adds Withdrawn Note based on lookup
"""
if item_lookups.get(item.get('barcode'), {}).get("withdrawn?", False):
note = {"note": "Withdrawn in Symphony", "type": note_types.get("Withdrawn")}
if "notes" in item:
item["notes"].append(note)
else:
item["notes"] = [
note,
]


def _add_additional_info(**kwargs) -> None:
"""Generates notes from tsv files"""
airflow: str = kwargs["airflow"]
Expand All @@ -213,7 +241,7 @@ def _add_additional_info(**kwargs) -> None:
tsv_notes_path = pathlib.Path(tsv_notes_path)
tsv_notes_df = pd.read_csv(tsv_notes_path, sep="\t", dtype=object)

item_note_types = _retrieve_item_notes_ids(folio_client)
item_note_types = _retrieve_item_notes_ids(folio_client)

items_lookup = _generate_items_lookups(airflow, items_tsv_path, folio_client)

Expand All @@ -229,6 +257,7 @@ def _add_additional_info(**kwargs) -> None:
_set_discovery_suppress(item, items_lookup)
if "codes" in items_lookup.get(item.get("barcode"), {}):
item["statisticalCodeIds"] = items_lookup[item.get("barcode")]["codes"]
_set_withdrawn_note(item, items_lookup, item_note_types)
items.append(item)

if not len(items) % 1000:
Expand Down
21 changes: 19 additions & 2 deletions tests/test_items.py
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,7 @@
run_items_transformer,
_add_additional_info,
_generate_item_notes,
_set_withdrawn_note,
_remove_on_order_items,
)

Expand All @@ -35,6 +36,7 @@ def test_items_transformers():
{"id": "e9f6de86-e564-4095-a61a-38c9e0e6b2fc", "name": "Tech Staff"},
{"id": "62fd6fcc-5cde-4a74-849a-66e2d77a1f12", "name": "Public"},
{"id": "1d14675c-c163-4502-98f9-961cd3d17ab2", "name": "Circ Staff"},
{"id": "abeebfcc-53f9-4aea-ad80-561bebd99754", "name": "Withdrawn"},
]
}

Expand Down Expand Up @@ -92,7 +94,8 @@ def mock_get(*args, **kwargs):
"1233455\ta note\tCIRCSTAFF\n",
"1233455\ta note for the public\tCIRCNOTE\n",
"55678446243\tavailable for checkout\tPUBLIC\n",
"55678446243\ttf:green, hbr 9/20/2013\tTECHSTAFF",
"55678446243\ttf:green, hbr 9/20/2013\tTECHSTAFF\n",
"8772580-1001\tAt Hoover\tHVSHELFLOC",
]

items_recs = [
Expand All @@ -116,6 +119,10 @@ def mock_get(*args, **kwargs):
"holdingsRecordId": "fc473c74-c811-4ae9-bcd9-387a1d10b967",
"barcode": "0267132027",
},
{
"holdingsRecordId": "a36e1aa4-e965-522a-8afb-dceac63f4206",
"barcode": "8772580-1001",
},
]

items_tsv = [
Expand All @@ -125,6 +132,7 @@ def mock_get(*args, **kwargs):
"145623\t1\t1\t4614642357\tSAL3\tSPECB-S\tINPROCESS\tSTKS-MONO\t\tFED-WEED\t0\tLC\tRH640 .I34 1996\t\t0\tMARC\t0",
"262345\t1\t1\t7659908473\tSAL3\tINPROCESS\tINPROCESS\tSTKS-MONO\t\t\t1\tLC\tYU40 .J4 2096\t\t0\tMARC\t0", # ITEM SHADOW
"5559991\t1\t1\t7659908473\tSAL3\tINPROCESS\tINPROCESS\tSTKS-MONO\tDIGI-SENT\tFED-WEED\t0\tLC\tEG640 .J4 1796\t\t1\tMARC\t0", # CALL SHADOW
"8772580\t1\t1\t8772580-1001\tSUL\tSTACKS\tWITHDRAWN\tSTKS\t\t\t0\t1\tLC\tXX(8772580.1)\t0\tMARC\t0",
]


Expand Down Expand Up @@ -237,10 +245,11 @@ def test_add_additional_info(
assert "discoverySuppress" not in new_items_recs[1]
assert new_items_recs[2]["discoverySuppress"] is True
assert new_items_recs[3]["discoverySuppress"] is True
assert new_items_recs[-2]["statisticalCodeIds"] == [
assert new_items_recs[-3]["statisticalCodeIds"] == [
"8be8d577-1cd7-4b84-ae71-d9472fc4d2b1",
"9c98fbcc-1728-41f5-9382-038d9fa45c0f",
]
assert new_items_recs[-1]["notes"][1]["note"] == "Withdrawn in Symphony"


def test_add_additional_info_missing_barcode(
Expand Down Expand Up @@ -308,3 +317,11 @@ def test_remove_on_order_items(tmp_path):
_remove_on_order_items(source_path)
filtered_df = pd.read_csv(source_path, sep="\t")
assert len(filtered_df) == 1


def test_set_withdrawn_note_no_prior_notes():
item = {"barcode": "295013344"}
item_lookups = {"295013344": {"withdrawn?": True}}
_set_withdrawn_note(item, item_lookups, item_note_types)
assert item["notes"][0]["note"] == "Withdrawn in Symphony"
assert item["notes"][0]["type"] == item_note_types.get("Withdrawn")
Loading