From 9f4d478d4b303f1dce3bf2bb4349c575e70218ef Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jens=20K=C3=BCrten?= Date: Fri, 13 Feb 2026 14:26:13 +0100 Subject: [PATCH 1/2] feat: Add example for enforcing uniqueness of ERP Material No field --- docs/examples/enforce_field_rules.md | 56 ++++++++++++++++++++++++++++ 1 file changed, 56 insertions(+) diff --git a/docs/examples/enforce_field_rules.md b/docs/examples/enforce_field_rules.md index 1b8f676..21451ed 100644 --- a/docs/examples/enforce_field_rules.md +++ b/docs/examples/enforce_field_rules.md @@ -96,3 +96,59 @@ def parts_need_classification( ) ``` + + +### Enforce uniqueness of fields + +In some cases, you may want to ensure that certain fields are unique across all parts or documents in your system. +This example demonstrates how to enforce uniqueness of the *"ERP Material No"* field for parts before they are released. + +```python +from csfunctions import MetaData, Service +from csfunctions.actions import AbortAndShowErrorAction +from csfunctions.events import PartReleaseCheckEvent + +import requests + + +def find_duplicates(metadata: MetaData, materialnr_erp: str, teilenummer: str): + # we try to find parts with the same materialnr_erp but different teilenummer + graphql_url = str(metadata.db_service_url).rstrip("/") + "/graphql/v1" + query = f"""{{ + parts(_filter: {{materialnr_erp: {{eq: \"{materialnr_erp}\"}}, teilenummer: {{neq: \"{teilenummer}\"}}}}) {{ + materialnr_erp, + teilenummer, + t_index + }} + }} + """ + + response = requests.post( + graphql_url, + headers={"Authorization": f"Bearer {metadata.service_token}"}, + json={"query": query}, + ) + + response.raise_for_status() + parts = response.json()["data"]["parts"] + + return parts + + +def part_materialnr_unique(metadata: MetaData, event: PartReleaseCheckEvent, service: Service): + """ + Checks if an ERP number is already in use by a different part + """ + + for part in event.data.parts: + duplicates = find_duplicates( + metadata=metadata, materialnr_erp=part.materialnr_erp, teilenummer=part.teilenummer) + if duplicates: + existing_part_number = duplicates[0]["teilenummer"] + return AbortAndShowErrorAction(message=f"The ERP number {part.materialnr_erp} is already in use by part number {existing_part_number}.") +``` + +!!! note + This example only checks for duplicates during part release, but you can easily adapt it to other events like part creation or modification. + Keep in mind though, that field calculations run AFTER the check events, meaning you can't use this to check uniqueness of fields that are set via field calculation. + If you need to enforce uniqueness of calculated fields, you need to implement the uniqueness check within the field calculation itself. From 1606bffe52cc069c9e138c76bffaa19f80ac8ca4 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jens=20K=C3=BCrten?= Date: Fri, 13 Feb 2026 14:31:11 +0100 Subject: [PATCH 2/2] fix: Update warning about uniqueness checks in part release example --- docs/examples/enforce_field_rules.md | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/docs/examples/enforce_field_rules.md b/docs/examples/enforce_field_rules.md index 21451ed..34e912a 100644 --- a/docs/examples/enforce_field_rules.md +++ b/docs/examples/enforce_field_rules.md @@ -148,7 +148,7 @@ def part_materialnr_unique(metadata: MetaData, event: PartReleaseCheckEvent, ser return AbortAndShowErrorAction(message=f"The ERP number {part.materialnr_erp} is already in use by part number {existing_part_number}.") ``` -!!! note - This example only checks for duplicates during part release, but you can easily adapt it to other events like part creation or modification. - Keep in mind though, that field calculations run AFTER the check events, meaning you can't use this to check uniqueness of fields that are set via field calculation. +!!! warning + Keep in mind that field calculations run AFTER the check events, meaning you can't use this to check uniqueness of fields that are set via field calculation. + If you need to enforce uniqueness of calculated fields, you need to implement the uniqueness check within the field calculation itself.