diff --git a/src/albert/collections/lots.py b/src/albert/collections/lots.py index 96b71a17..35f1ae00 100644 --- a/src/albert/collections/lots.py +++ b/src/albert/collections/lots.py @@ -403,21 +403,22 @@ def adjust( else: delta = -current - patch_payload = PatchPayload( - data=[ - PatchDatum( - operation=PatchOperation.UPDATE, - attribute="inventoryOnHand", - old_value=str(existing_lot.inventory_on_hand), - new_value=self._format_inventory_delta(delta), - ) - ] - ) - payload = patch_payload.model_dump(mode="json", by_alias=True) - if description is not None: - payload["notes"] = description + if delta != 0: + patch_payload = PatchPayload( + data=[ + PatchDatum( + operation=PatchOperation.UPDATE, + attribute="inventoryOnHand", + old_value=str(existing_lot.inventory_on_hand), + new_value=self._format_inventory_delta(delta), + ) + ] + ) + payload = patch_payload.model_dump(mode="json", by_alias=True) + if description is not None: + payload["notes"] = description - self.session.patch(f"{self.base_path}/{lot_id}", json=payload) + self.session.patch(f"{self.base_path}/{lot_id}", json=payload) return self.get_by_id(id=lot_id) @validate_call @@ -450,22 +451,24 @@ def transfer( """ if quantity == "ALL": source_lot = self.get_by_id(id=lot_id) - patch_payload = PatchPayload( - data=[ - PatchDatum( - operation=PatchOperation.UPDATE, - attribute="storageLocation", - old_value=source_lot.storage_location.id - if source_lot.storage_location - else None, - new_value=storage_location_id, - ) - ] - ) - self.session.patch( - f"{self.base_path}/{lot_id}", - json=patch_payload.model_dump(mode="json", by_alias=True), + current_location_id = ( + source_lot.storage_location.id if source_lot.storage_location else None ) + if current_location_id != storage_location_id: + patch_payload = PatchPayload( + data=[ + PatchDatum( + operation=PatchOperation.UPDATE, + attribute="storageLocation", + old_value=current_location_id, + new_value=storage_location_id, + ) + ] + ) + self.session.patch( + f"{self.base_path}/{lot_id}", + json=patch_payload.model_dump(mode="json", by_alias=True), + ) return self.get_by_id(id=lot_id) transfer_quantity = quantity diff --git a/tests/collections/test_lots.py b/tests/collections/test_lots.py index 2aa35dcc..76132582 100644 --- a/tests/collections/test_lots.py +++ b/tests/collections/test_lots.py @@ -238,3 +238,37 @@ def test_transfer_all_quantity( assert updated_lot.inventory_on_hand == pytest.approx(seeded_lot.inventory_on_hand) assert updated_lot.storage_location is not None assert updated_lot.storage_location.id == destination.id + + +def test_transfer_all_same_location_no_op(client: Albert, seeded_lot: Lot): + """Test that transferring ALL to the current location does not raise an error.""" + current_location_id = seeded_lot.storage_location.id if seeded_lot.storage_location else None + assert current_location_id is not None, "Seeded lot must have a storage location" + + result = client.lots.transfer( + lot_id=seeded_lot.id, + quantity="ALL", + storage_location_id=current_location_id, + ) + assert result.id == seeded_lot.id + assert result.storage_location is not None + assert result.storage_location.id == current_location_id + + +def test_adjust_set_no_op(client: Albert, seeded_lot: Lot): + """Test that SET to the current inventory value does not raise an error.""" + result = client.lots.adjust( + lot_id=seeded_lot.id, + action=LotAdjustmentAction.SET, + quantity=seeded_lot.inventory_on_hand, + ) + assert result.inventory_on_hand == pytest.approx(seeded_lot.inventory_on_hand) + + +def test_adjust_zero_no_op(client: Albert, seeded_lot: Lot): + """Test that ZERO on a lot already at zero does not raise an error.""" + # First zero it out + client.lots.adjust(lot_id=seeded_lot.id, action=LotAdjustmentAction.ZERO) + # Zero again — should be a no-op without error + result = client.lots.adjust(lot_id=seeded_lot.id, action=LotAdjustmentAction.ZERO) + assert result.inventory_on_hand == pytest.approx(0)