Datenbanken II – Angebotssoftware, kundenspezifische Regeln

(Auszug aus "Schematron - Effiziente Business Rules für XML-Dokumente", Kapitel 8)

Ein weiteres Beispiel aus dem Bereich Datenbanken zeigt im Folgenden die Verwendung von Schematron als Sprache zur Überprüfung von Berechnungen. Ein Unternehmen baut Drucker und verkauft, least, überlässt oder vermietet sie an Kunden. Den eigentlichen Gewinn erzielt das Unternehmen aber mit den Verbrauchsmaterialien wie Tintenpatronen und Tonern, die mit den Geräten verkauft werden. Da die Preise der Verbrauchsmaterialien mit der Vertriebsvariante des Druckers (Verkauf, Leasing, Überlassung oder Vermietung) zusammenhängen, ergibt sich unter Umständen ein anderer Preis für die Verbrauchsmaterialien je nach Vertriebsvariante.

Die Idee dahinter ist, dass einem Kunden ein Drucker überlassen wird und er sich dafür verpflichtet, eine bestimmte Anzahl an Tonern in den nächsten 12 Monaten zu erwerben. Das bedeutet nun für den Preis des Toners, dass dieser höher sein muss als bei einem verkauften Drucker.

Bei der interaktiven Anfertigung eines Angebotsschreibens für einen Kunden muss dem jeweiligen System eine XML-Datei vorliegen, die die verschiedenen Informationen zur Preisgestaltung beinhaltet, auch wenn sie unter Umständen nicht unmittelbar in diesem konkreten Fall gebraucht werden. Ein Beispiel wäre, dass die Preise für die einzelnen Verbrauchsmaterialien in Abhängigkeit von der Vertriebsart immer auch im XML-Dokument vorgehalten und dann abhängig von der Bestellung für die Angebotserstellung herangezogen werden. In einem anderen Anwendungsfall ließe sich für denselben Export (XML-Instanz) die jeweilige Gewinnmarge für das Vertriebsmodell ermitteln, um dann aus ökonomischer Betrachtung das optimale Vertriebsmodell für das Unternehmen zu ermitteln.

Neben dem beschriebenen Workflow ist es denkbar, die Businesslogiken in die Datenbank zu implementieren und eine jeweils passende Instanz zur Generierung des Angebots auszugeben. Bei Anpassungen der Datenbank müssen in diesem Fall auch immer die vielzähligen Businesslogiken überprüft und aktualisiert werden, weshalb sich bei hochkomplexen Anwendungen die oben skizzierte Aufteilung bewährt hat.

Aus diesem Aufbau und der damit verbundenen Verschiebung der Businesslogiken in die XML-Instanz ergeben sich für unser Beispiel inhaltliche Bedingungen, die nicht mit dem XML-Schema sichergestellt werden können. Einige dieser Businessregeln könnten zwar problemlos auch durch Datenbank-Constraints abgeprüft werden, die Praxis zeigt allerdings, dass bei sehr komplexen Anwendungen immer wieder inhaltliche Inkonsistenzen in den Materialstammdaten oder in den Abfragen bis in den XML-Export durchschlagen. Schematron ist in diesem Anwendungsfall (neben XML Schema) nicht die einzige Prüfsprache, sondern nur eine zusätzliche Qualitätssicherungsmaßnahme.

Im Folgenden wird nun ein sehr vereinfachtes Beispiel gezeigt:

Datenbankschema eines Angebotsprozesses

Abbildung: Datenbankschema eines Angebotsprozesses

In einem Angebots-Schema werden Angebote für einen oder mehrere Kunden gebündelt.

Jeder Kunde (<kunde>) hat eine ID (<kundeId>) und einen Namen (<name>). Die zu bestellenden Waren werden über eine ID-IDREF-Beziehung mit den Kunden verbunden. Das Element, das die jeweiligen Produkte auszeichnet, ist <produktId>. Im Element <preis> wird der Umsatz des Kunden erfasst.

Alle Produkte werden in einem gleichnamigen Top-Level-Element gesammelt. Analog zu den Kunden hat jedes Produkt eine <produktId> und einen Namen (<name>). Außerdem werden alle Kunden, die dieses Produkt bestellen, über die ID <kundeId> verbunden. Das Element <preis> gibt den Preis des Produktes an. Das letzte Top-Level-Element <preis> ist der Gesamtpreis aller angebotenen Produkte.

Nachfolgend stellen wir nun ein Beispiel mit verschiedenen logischen Fehlern dar, die im Anschluss erläutert werden:

<angebot xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="angebot.xsd">
  <kunden>
    <kunde>
      <kundeId>KU000001</kundeId>
      <name>data2type</name>
      <produktId>PRO000001</produktId>
      <produktId>PRO000002</produktId>
      <preis>5.33</preis>
    </kunde>
    <kunde>
      <kundeId>KU000002</kundeId>
      <name>HAL</name>
      <produktId>PRO000003</produktId>
      <produktId>PRO000004</produktId>
      <preis>10.33</preis>
    </kunde>
  </kunden>
  <produkte>
    <produkt>
      <produktId>PRO000001</produktId>
      <name>Toner 01 Schwarz</name>
      <kundeId>KU000001</kundeId>
      <preis>1.00</preis>
    </produkt>
    <produkt>
      <produktId>PRO000002</produktId>
      <name>Toner 01 Gelb</name>
      <kundeId>KU000001</kundeId>
      <preis>3.33</preis>
    </produkt>
    <produkt>
      <produktId>PRO000003</produktId>
      <name>Toner 01 Cyan</name>
      <kundeId>KU000001</kundeId>
      <kundeId>KU000002</kundeId>
      <preis>1.00</preis>
    </produkt>
    <produkt>
      <produktId>PRO000004</produktId>
      <name>Toner 02 Schwarz</name>
      <kundeId>KU000002</kundeId>
      <preis>5.33</preis>
    </produkt>
  </produkte>
  <preis>14.33</preis>
</angebot>

In diesem vereinfachten Szenario gibt es mehrere potenzielle Fehlerquellen. Ein Problemfeld könnten die Preise sein, denn dort gibt es Zusammenhänge zwischen den Produktpreisen und den Bestellwerten. Eine Regel lautet: Der Wert aller Waren pro Kunde (Inhalt von <preis> in <kunde>) muss der Summe aller Produktpreise der angebotenen Produkte entsprechen. Außerdem muss der Gesamtwert der angebotenen Waren der Summe der Warenwerte aller Kunden entsprechen. In unserem Beispiel werden diese Regeln nicht eingehalten. Der zweite Kunde HAL hat ein Angebot für Produkt Toner 01 Cyan und Toner 02 Schwarz erhalten. Beide Produkte haben in der Summe einen Preis von 6.33. Stattdessen steht beim <preis> des Kunden 10.33.

Das Pattern zur Überprüfung der Businessregel lautet:

<pattern id="kundenpreis">
  <rule context="kunde/preis">
    <let name="kundeId" value="parent::kunde/kundeId"/>
    <assert test="sum(//produkt[kundeId=$kundeId]/preis)=.">Die Summe stimmt an dieser Stelle nicht. Sie müsste <value-of select="sum(//produkt[kundeId=$kundeId]/preis)"/> lauten.</assert>
  </rule>
</pattern>

Ein weiterer Fehler findet sich im Gesamtvolumen des Auftrages. Hierzu ist ein Preis von 14.33 eingetragen. Die Summe aller angebotenen Produkte ergibt allerdings 11.66. Das Pattern, um diese Fehlerquelle auszuschließen, lautet:

<pattern id="angebotspreis">
  <rule context="angebot/preis">
    <assert test="sum(//kunde/preis)=.">Die Summe stimmt an dieser Stelle nicht. Sie müsste <value-of select="sum(//kunde/preis)"/> lauten.</assert>
  </rule>
</pattern>

Ein weiterer, in unserem Beispiel vorkommender Fehler besteht darin, dass zwar ID-IDREF-Beziehungen mittels DTDs oder XML Schemata überprüft werden können und dass ein Kunde, der ein Produkt-Angebot erhält, auch existiert, allerdings ist dadurch nicht sicher gestellt, dass bei diesem Produkt gleichzeitig auch der Kunde eingetragen wurde.

In dem oben aufgeführten Beispiel wurde das folgende Produkt zwei Kunden angeboten:

<produkt>
  <produktId>PRO000003</produktId>
  <name>Toner 01 Cyan</name>
  <kundeId>KU000002</kundeId>
  <kundeId>KU000001</kundeId>
  <preis>1.00</preis>
</produkt>

Umgekehrt wurde aber bei einem Kunden (<kundeId>KU000001</kundeId>) nicht das korrekte Produkt (<produktId>PRO000003</produktId>) eingetragen.

<kunde>
  <kundeId>KU000001</kundeId>
  <name>data2type</name>
  <produktId>PRO000001</produktId>
  <produktId>PRO000002</produktId>
  <preis>4.33</preis>
</kunde>

Entsprechend muss für jeden Kunden überprüft werden, ob die Liste der Produkt-IDs vollständig ist:

<pattern id="verbindungProdukt">
  <rule context="kunde">
    <let name="missings" value="//produkt[kundeId = current()/kundeId]/produktId[not(.=current()/produktId)]"/>
    <report test="count($missings) &gt; 0">Hier fehlt/en die Produkt-ID(s): <value-of select="string-join($missings, ', ')"/>.</report>
  </rule>
</pattern>

   

<< zurück vor >>

 

 

 

Tipp der data2type-Redaktion:
Zum Thema Schematron bieten wir auch folgende Schulungen zur Vertiefung und professionellen Fortbildung an:

Copyright © dpunkt.verlag GmbH 2011
Für Ihren privaten Gebrauch dürfen Sie die Online-Version ausdrucken. Ansonsten unterliegt dieses Kapitel aus dem Buch "Schematron - Effiziente Business Rules für XML-Dokumente" denselben Bestimmungen, wie die gebundene Ausgabe: Das Werk einschließlich aller seiner Teile ist urheberrechtlich geschützt. Alle Rechte vorbehalten einschließlich der Vervielfältigung, Übersetzung, Mikroverfilmung sowie Einspeicherung und Verarbeitung in elektronischen Systemen.

dpunkt.verlag GmbH, Ringstraße 19B, 69115 Heidelberg, fon 06221-14830, fax 06221-148399, hallo(at)dpunkt.de