DEXPRO AWF Externe Genehmigungen — SharePoint-Integrationsvertrag
Dieses Dokument beschreibt den SharePoint-Listen-Vertrag zwischen Business Central (der AWF-Erweiterung) und jedem externen System, das Genehmigungsanfragen konsumiert oder beantwortet. Er ist transportneutral: Die Referenzimplementierung verwendet Power Automate + Microsoft Teams,Teams (siehe SETUP-GUIDE.de-DE.md), aber jedes System, das SharePoint-Listenelemente über die Microsoft Graph API — oder die native SharePoint-REST-API — lesen und schreiben kann, kann teilnehmen.
Zielgruppe: Integrationsentwickler. Die Endbenutzereinrichtung ist in
EinrichtungshandbuchSETUP-GUIDE.de-DE.mdbeschrieben.
1. Designprinzipien
2. Abfragemodell
- BC führt einen Aufgabenwarteschlangenposten (
Codeunit 70954832 "DXP AWF Ext. Approval Poller") in einem wiederkehrenden Intervall aus (Standard: alle 2 Minuten). - Der Poller ruft Elemente ab, die
Processed eq false and ApprovalStatus ne 'Pending' and BCCompanyName eq '<aktuelles Unternehmen>'entsprechen (serverseitiger Filter; fällt auf clientseitigen Filter zurück, wenn Graph den Filter ablehnt). Die Unternehmens-Klausel wird immer angewendet — siehe § 7a. - Für jedes übereinstimmende Element aktualisiert BC den entsprechenden AWF-Eintrag, ruft die Workflow-Engine auf, setzt dann
Processed = trueauf dem SharePoint-Element und versucht, es zu löschen (DELETE). - Schlägt
DELETEfehl, reicht das FlagProcessed = trueaus, um das Element aus nachfolgenden Abfragen auszuschließen; verwaiste Elemente werden vonCleanupOrphanedSPItemsin jedem Zyklus erneut versucht.
Auswirkungen für Konsumenten: Zwischen dem Schreiben der Entscheidung und der BC-Verarbeitung liegen zwischen 0 und N Minuten (wobei N das Abfrageintervall ist). Erwarten Sie keine synchrone Bestätigung. Wenn Sie eine Rückmeldung benötigen, beobachten Sie das Processed-Feld des Elements oder dessen Verschwinden.
3. Spaltenreferenz
Jede Spalte unten verwendet den internen name — das ist der Vertrag. Anzeigenamen können lokalisiert sein.
3.1 Eingaben (BC → Konsument)
BC befüllt diese beim Erstellen des Elements. Konsumenten dürfen sie nicht ändern.
| Name | Typ | Hinweise | |
|---|---|---|---|
SchemaVersion | Text | Aktuell "1". Erhöhung zeigt eine brechende Änderung in diesem Vertrag an. | |
BCCompanyName | Text | Das BC-Unternehmen, dem der Eintrag gehört. Immer bei neuen Zeilen gesetzt; darf von Konsumenten nicht geändert werden. Der unternehmensspezifische Poller von BC verwendet dies, um Elemente anderer Unternehmen zu ignorieren (siehe § 7a). | |
Title | Text | Kurze Datensatzbeschreibung (z. B. Bestellnummer). Teil der integrierten SharePoint-Spalte. | |
BCEntryNo | Text | Lfd. Nr. des AWF-Externen Genehmigungseintrags innerhalb von BCCompanyName. Nicht global eindeutig — immer mit BCCompanyName kombinieren, wenn Elemente korreliert werden. | |
BCApprovalEntryNo | Text | Lfd. Nr. des zugrundeliegenden BC-Standard-Genehmigungspostens (Tabelle 454). Identisch über alle Peer-Zeilen in einer Gruppe — nützlich zum Gruppieren von Zeilen nach ihrer zugrundeliegenden Entscheidungseinheit (z. B. Peer-Elemente stornieren, wenn einer übernimmt). | |
BCInstanceID | Text | AWF-Workflow-Instanz-GUID — global eindeutig über alle Unternehmen. | |
Description | Text | Lokalisierter | Format(RecId, , z. B. Einkaufszeile: Rechnung,EKRECH1052,20000 mit übersetzten Tabellen-/Feldbezeichnungen). Wird auf der Karte als Datensatzzeile gezeigt; funktioniert für jede Tabelle. |
ApproverEmail | Text | UPN / E-Mail-Adresse. Benachrichtigungen an diese Adresse weiterleiten. | |
ApproverDisplayName | Text | Für Menschen lesbarer Name. | |
AttachmentsUrl | Text | SharePoint-Freigabelink zu einem Ordner mit Dokumentanhängen. Leer, wenn der Upload deaktiviert ist oder keine Anhänge vorhanden sind. | |
BCDocumentUrl | Text | Direktlink zum Quelldatensatz in Business Central. | |
RecordDetails | Mehrzeiliger Text | CommonMark-Markdown-Darstellung der eigenen Felder des genehmigten Datensatzes (z. B. für eine Einkaufszeile: Art, Nr., Beschreibung, Menge, Einkaufspreis, Zeilenbetrag). Direkt in einem Adaptive-Card-TextBlock mit wrap=true darstellbar. Auf die häufigsten Verkaufs-/Einkaufskopf- und Zeilentabellen zugeschnitten; fällt für andere Tabellen auf einen generischen Feld-Walk zurück. | |
IsGroupApproval | Boolesch | true, wenn dieses Element eines von mehreren für eine übernahmebasierte Gruppengenehmigungs-Anfrage ist. | |
GroupCode | Text | Code der externen Genehmigergruppe (nur gesetzt, wenn IsGroupApproval = true). | |
Amount | Text | Formatierter Betrag (sprachabhängig). | |
AmountRaw | Zahl | Maschinenlesbarer Betrag (immer Punkt als Dezimaltrennzeichen). Hierfür gegenüber Amount bevorzugen. | |
DueDate | Text | Formatiertes Datum. | |
DueDateRaw | Datum/Uhrzeit | ISO 8601, UTC. Hierfür gegenüber DueDate bevorzugen. | |
CreatedRaw | Datum/Uhrzeit | ISO 8601, UTC. Wann das Element von BC erstellt wurde. | |
SenderName | Text | Anzeigename | des Anforderers (User."Full Name"); fällt auf die BC-Benutzer-ID |
StageName | Text | Beschreibung des Workflow-Schritts. | |
LblTitle … LblClaimedSuccessMsg | Text | Vorübersetzte UI-Zeichenfolgen und Nachrichtenvorlagen für die Sprache des Genehmigers (siehe 3.4). Die LblAlready…Msg- und LblClaimedSuccessMsg-Spalten enthalten Nachrichtenvorlagen mit {title}- / {claimer}-Platzhaltern, die der Konsument (z. B. Power Automate) zur Laufzeit ersetzt. |
3.2 Antwortfelder (Konsument → BC)
Der Konsument schreibt diese einmal, wenn eine Entscheidung getroffen wurde. Nur ApprovalStatus ist erforderlich.
| Name | Typ | Erforderlich | Hinweise |
|---|---|---|---|
ApprovalStatus | Auswahlfeld | Ja | Eines von Approved, Rejected, Claimed. BC-seitig Groß-/Kleinschreibung unempfindlich. SharePoint zeigt ein Dropdown mit allen gültigen Werten; der anfängliche/Standardwert ist Pending. Jeder nicht-terminale Wert wird von BC protokolliert und das Element wird in Ruhe gelassen. |
ResponseComment | Mehrzeiliger Text | Nein | Freitext, max. 2048 Zeichen auf der BC-Seite. SharePoint zeigt einen mehrzeiligen Textbereich zur Bearbeitung. Wird in BCs Genehmigungskommentarverlauf angezeigt. |
ResponseDateTime | Datum/Uhrzeit | Nein | ISO 8601 UTC über Graph, native Auswahl in SP. Wenn weggelassen, verwendet BC die aktuelle Uhrzeit. |
ClaimedBy | Text | Ja, wenn ApprovalStatus = Claimed | E-Mail des Gruppenmitglieds, das den Eintrag übernommen hat. BC schreibt diese Spalte auch in Peer-Elemente, die storniert werden, weil jemand anderes in der Gruppe zuerst übernommen hat — in diesem Fall identifiziert sie den Benutzer, der den Eintrag übernommen hat (der ApprovalStatus des SP-Elements ist dann gleichzeitig Cancelled). |
TeamsMessageId | Text | Nein | Die Microsoft-Teams-Message-ID der Adaptive Card, die der Konsument für dieses Element gepostet hat. Ein Konsument, der Peer-Karten schließen möchte (die noch offene Karte eines Gruppenmitglieds ersetzen, sobald ein anderes entscheidet), schreibt diese direkt nach dem Posten der Karte zurück und liest die Werte der Peers während der Übernahme-Kaskade, um Adaptive Card aktualisieren zu adressieren. BC speichert sie ebenfalls (und akzeptiert sie über die setTeamsMessageId-Bound-Action) für Diagnosezwecke. Optional — leer lassen, wenn der Konsument kein Karten-Schließen implementiert. |
Nicht schreiben:
Processed,SchemaVersion,BCEntryNo,BCInstanceIDoder irgendeineLbl*-Spalte. BC besitzt diese. (TeamsMessageIdist neben den Antwortfeldern oben die einzige vom Konsumenten beschreibbare Transportspalte.)
3.3 BC-verwalteter Zustand
| Name | Typ | Geschrieben von | Zweck |
|---|---|---|---|
Processed | Boolesch | Nur BC | true, sobald BC die Antwort konsumiert hat. Der Poller schließt diese aus nachfolgenden Abrufen aus. Konsumenten müssen diese als schreibgeschützt behandeln. |
3.4 Lokalisierte Beschriftungsspalten
BC übersetzt die Adaptive-Card-/UI-Beschriftungen für die Sprache des Genehmigers vor und schreibt sie als Klartext. Konsumenten können sie direkt verwenden, ohne BC oder einen Übersetzungsdienst aufzurufen.
| Name | Typischer englischer Wert |
|---|---|
LblTitle | Approval Request |
LblApprove | Approve |
LblReject | Reject |
LblComment | Comment |
LblClaim | Claim |
LblRelease | Release |
LblAmount | Amount |
LblSender | Requested by |
LblDueDate | Due Date |
LblStage | Stage |
LblDescription | Description |
LblAttachments | Approval Documents |
LblOpenInBC | Open in Business Central |
LblDetails | Details |
LblAlreadyClaimedByMsg | This approval ({title}) has already been claimed by {claimer}. You can safely ignore this card. |
LblAlreadyHandledMsg | This approval ({title}) has already been handled by another approver or cancelled in Business Central. You can safely ignore the earlier card. |
LblClaimedSuccessMsg (Anzeigename Decision Confirmation) | The approval entry "{title}" has been successfully processed. |
LblApprovedResult (Anzeigename Approved (Result)) | Approved |
LblRejectedResult (Anzeigename Rejected (Result)) | Rejected |
LblResultTitle (Anzeigename Result Title) | Approval Decision |
LblClosedTitle (Anzeigename Closed Title) | No Longer Open |
LblResponseSent (Anzeigename Response Sent) | Response sent. |
4. ApprovalStatus-Zustandsautomat
┌─────────┐ Konsument schreibt ┌──────────┐
│ Pending │──────────────────────▶ │ Approved │ ─┐
└────┬────┘ └──────────┘ │
│ │ BC-Poller
│ Konsument schreibt │ liest ab,
▼ │ setzt Processed=true,
┌──────────┐ │ dann DELETE
│ Notified │──────────────▶ Approved / Rejected ────┤
└────┬─────┘ │
│ │
│ Gruppenübernahme │
▼ │
┌─────────┐ │
│ Claimed │──────────────▶ Approved / Rejected ─────┘
└─────────┘
Pending— von BC beim Erstellen geschrieben.Notified(optional) — Konsument kann dies setzen, nachdem der Genehmiger benachrichtigt, aber noch nicht geantwortet hat. Rein informativ; BC reagiert nicht darauf.Claimed— nur Gruppengenehmigungs-Anfragen. Konsument muss auchClaimedBysetzen.Approved/Rejected— terminal. Konsument kann auchResponseCommentundResponseDateTimesetzen.Processed,Error,Cancelled— BC-interne terminale Zustände. Nicht schreiben.
4a. Direkt in SharePoint genehmigen (ohne Konsumentenanwendung)
Da die Liste typisierte Spalten verwendet, kann ein Mensch einen Eintrag genehmigen, indem er das Listenelement in SharePoint öffnet und bearbeitet — kein Teams, kein Power Automate, kein BC-Zugang erforderlich:
Der Aufgabenwarteschlangen-Poller von BC liest die Änderung beim nächsten Zyklus ab (Standard: alle 2 Minuten) und verarbeitet sie durch den Genehmigungsworkflow identisch zu einem Power-Automate-Rückschreib.
Berechtigungen: Der SharePoint-Benutzer benötigt Bearbeitungsberechtigungen für die Liste. Da die Spalten
Processed,SchemaVersion,BCEntryNoundLbl*BC-eigentum sind, sollten Sie eine SharePoint-Ansicht oder Spaltenebenformatierung verwenden, um sie aus dem Bearbeitungsformular auszublenden — Benutzer benötigen nurApprovalStatus(Genehmigungsstatus),ResponseComment(Antwortkommentar),ResponseDateTime(Antwort am) und (für Übernahme)ClaimedBy(Übernommen von).
5. Minimale Antwort-Payload
Genehmigen
PATCH /sites/{siteId}/lists/{listId}/items/{itemId}/fields HTTP/1.1
Authorization: Bearer ...
Content-Type: application/json
{
"ApprovalStatus": "Approved",
"ResponseComment": "Sieht gut aus.",
"ResponseDateTime": "2026-04-22T10:15:00Z"
}
Ablehnen
{ "ApprovalStatus": "Rejected", "ResponseComment": "Doppelte Bestellung." }
Übernehmen (Gruppengenehmigungs-Anfrage)
{ "ApprovalStatus": "Claimed", "ClaimedBy": "maria@contoso.com" }
6. Alternative: Native BC-API
- Publisher:
dexpro - Group:
advancedWorkflow - Version:
v1.0 - Entity:
externalApprovalEntries - Gebundene Aktionen:
approve,reject,claim,releaseClaim,markNotified
Beispiel:
POST /api/dexpro/advancedWorkflow/v1.0/companies({id})/externalApprovalEntries({entryNo})/Microsoft.NAV.approve
{ "comment": "Sieht gut aus." }
7a. BC-Installationen mit mehreren MandantenUnternehmen
Auswirkungen für Konsumenten:
- Behandeln Sie immer
(BCCompanyName, BCEntryNo)als zusammengesetzten Schlüssel.BCEntryNoallein ist nur innerhalb eines einzelnen Unternehmens eindeutig. - Schreiben oder ändern Sie
BCCompanyNamenicht. BC setzt es bei der Elementerstellung und ändert es nie. BCInstanceID(GUID) ist global eindeutig und ein sicherer Korrelationsschlüssel ohneBCCompanyName.- Wenn Sie einen Power-Automate-Flow aufbauen, der Elemente schreibt (z. B. eine benutzerdefinierte Aufnahme), setzen Sie
BCCompanyNameauf das Zielunternehmen, sonst sieht der BC-Poller Ihre Elemente nie.
7. Versionierung
- Additive Änderungen (neue Spalten, neue optionale Antwortfelder) erhöhen
SchemaVersionnicht. Konsumenten müssen unbekannte Felder ignorieren. BreakingBrechendeChangesÄnderungen (umbenannte Spalten, geänderte Semantik, erforderliche Antwortfelder) erhöhenSchemaVersion. BC schreibt weiterhin die alte Schema-Version, bis ein Deprecation-Release angekündigt wird.- Konsumenten sollten
SchemaVersionbei jedem Element validieren und Elemente ablehnen, deren Version sie nicht verstehen.
8. Problembehandlungs-Checkliste für Integratoren
| Symptom | Wahrscheinliche Ursache |
|---|---|
| BC verarbeitet eine Antwort nie | ApprovalStatus ist keines von Approved/Rejected/Claimed; oder der Konsument hat Processed=true geschrieben; oder AWF-Einrichtung hat SP Approvals Enabled = Nein. |
| Element erscheint immer wieder in Abfragen | Processed wurde vom Konsumenten nicht berührt (erwartet) und DELETE schlägt serverseitig fehl — prüfen Sie Graph-App-Berechtigungen (Sites.ReadWrite.All). BC setzt Processed=true vor dem Löschen, sodass ein einzelner Processed-Flip in der UI typischerweise nicht benötigt wird. |
| Übernahme gelingt für zwei Mitglieder | Konsument hat ApprovalStatus=Claimed geschrieben, ohne den aktuellen Status zuerst zu prüfen. Bevorzugen Sie die gebundene BC-API-Aktion claim — sie erzwingt optimistisches Sperren. |