Einleitung

Der Offer-Workflow beschreibt das Vorgehen, wenn der Buyer beim Seller vorerst Spots nur reservieren möchte, ohne sie zu buchen.
Der Buyer erfragt sinngemäß ein Angebot (Offer) vom Seller.
Der Seller antwortet mit den reservierten Spots und gibt zudem eine zeitliche Indikation, bis zu welchem Datum und zu welcher Uhrzeit die Reservierung gültig sein wird.
Der Buyer hat die Möglickeiten, das Angebot durch eine Buchung anzunehmen, das Angebot durch eine explizite Stornierung abzulehnen oder das Angebot durch eine Änderung neu zu erfragen.
Handelt der Buyer nicht, verfällt quasi das Angebot, es kommt also nicht zu einer Buchung.
Der Seller kann (muss es aber nicht) durch einen SellerSync ebenfalls das erstellte Angebot zurückziehen oder verändern.

Allgemeine Grundsätze

Die folgenden Grundsätze müssen beim Offer-Workflow beachtet werden:

  • Buchungen und Angebote müssen sauber voneinander getrennt sein, daher gibt es keine Mischungen von Spots, die gebucht oder reserviert werden sollen, innerhalb eines Requests.
  • Sobald in einem RequestStream eine Buchung stattgefunden hat, dürfen keine Requests zur Erfragung eines Angebotes gestellt werden. Diese müssen in einem neuen RequestStream (ggf. in einem neuen PlanElement, wenn z.B. zum selben SellerProduct Angebote erfragt werden sollen) stattfinden.
  • Soll ein Angebot gebucht werden, so kann es nur in der Form gebucht werden, wie der Seller es in seiner Answer bereitgestellt hat. Wenn das Angebot des Seller dem Buyer nicht zusagt, so kann dieser einen weiteren "Offer-Request" erstellen, in der zunächst die gewünschte Angebotsform erfragt und ggf. vom Seller entsprechend beantwortet wird. In einem zweiten Schritt kann dann das neue Angebot gebucht werden.
  • Angebote sind an zwei Stellen kenntlich gemacht: durch die Enumeration Mode auf der Request-Answer-Ebene und durch Flags auf den entsprechenden Request- und AnswerSpots. Der requestMode-Wert auf dem Request ist immer äquivalent zu dem Flag isOfferauf allen anhängenden RequestSpots. Der answerMode-Wert auf der Answer ist immer äquivalent zu dem Flag isOfferauf allen anhängenden AnswerSpots.
  • Buyer und Seller können frei entscheiden, ob sie beim Erstellen eines Requests bzw. einer Answer das Flag auf der Request/ Answer-Ebene setzen wollen oder das Flag auf allen Request- bzw. AnswerSpots setzen. Gleiches gilt für das Lesen von Requests und Answers bzw. RequestSpots und AnswerSpots.

Grundsätzliches Vorgehen

Um als Buyer ein Angebot zu erfragen, gibt es zwei Möglichkeiten.
Zum einen kann er explizit beim Erstellen (CreateRequestInput) das Flag createOfferOnly auf true setzen. Somit wird im erstellten Request der requestMode-Wert auf OFFER gesetzt. Dies signalisiert dem Seller den Wunsch, die angefragten RequestSpots im Request zu reservieren (es erfolgt keine Buchung).

Alternativ dazu kann der Buyer auch das Flag isOfferauf allen RequestSpots auf true setzen, um ein Angebot zu erfragen.

OfferRequest cluster SpotA_B1 Spot 1 isOffer: true SpotB_B1 Spot 2 isOffer: true SpotC_B1 Spot 3 isOffer: true

In beiden Fällen ist in dem erstellten Request der requestMode-Wert OFFER.

OfferRequest cluster_buyerSpots1 Request1 Request 1 requestMode: OFFER

Der Seller antwortet auf eine Angebotsanfrage entweder indem im createAnswerInput das Flag isOffer = true

oder aber das Flag isOffer = trueauf allen AnswerSpots gesetzt wird.

OfferRequest cluster SpotA_S1 Spot 1 isOffer: true SpotB_S1 Spot 2 isOffer: true SpotC_S1 Spot 3 isOffer: true

In beiden Fällen ist in der erstellten Answer der answerMode-Wert OFFER.

OfferRequest cluster_Answer1 Answer1 Answer 1 state: CONFIRMED answerMode: OFFER

Zusätzlich kann der Seller das Feld offerValidUntil = <DateTime> setzen, welches dem Buyer signalisiert, wie lange das Angebot gültig bleiben wird.

Info Hinweis:
Hinweis: Das Feld offerValidUntil ist ein rein informatives Feld. Ob das Angebot tatsächlich zu diesem Zeitpunkt verfällt oder weiterhin gültig bleibt obliegt allein dem Seller.

Info Hinweis:
Hinweis: Wird das Flag auf Request-Answer-Ebene UND auf allen RequestSpots bzw. AnswerSpots gesetzt, so wird dies akzeptiert, sofern die Flags alle den gleichen Wert haben.


Beispiele

Hier folgen Beispiele, die die Wirkungsweise des Offer-Workflows verdeutlichen sollen.

Info Hinweis:
Hinweis: Bei den Beispielen ist jeweils beim Erstellen des ersten Requests das Flag createOfferOnly bzw. das Flag isOffer beim Erstellen der ersten Answer auf true gesetzt worden. Somit hat der zugehörige requestMode bzw. answerMode den Wert OFFER. Die folgenden Beispiel funktionieren in gleicher Art und Weise, wenn das Flag isOfferauf den RequestSpots bzw. AnswerSpots gesetzt worden ist.



Buchen eines Angebots

Soll ein Angebot gebucht werden, so kann dies nur in der Form geschehen, wie es vom Seller in seiner letzten Answer erstellt worden ist. Hierzu wird ein neuer Request erstellt und im CreateRequestInput das Flag createOfferOnly = false gesetzt bzw. das Flag isOffer = false auf allen RequestSpots. Der requestMode-Wert im erstellten Request ist somit nun ORDER. Die RequestSpots müssen den AnswerSpots der letzten Answer entsprechen und daher folgt logisch, dass action=KEEP auf allen RequestSpots beim Buchen einer Answer gesetzt sein muss.

OfferRequest platzhalter_Reihe1_klein->platzhalter_Reihe4_klein RequestStream RequestStream platzhalter_Reihe1_klein->RequestStream Request1 Request 1 requestMode: OFFER Answer1 Answer 1 state: CONFIRMED answerMode: OFFER SpotA_B1 Spot 1 isOffer: true SpotA_S1 Spot 1 isOffer: true Request2 Request 2 requestMode: ORDER platzhalter_Reihe4_klein->Request2 Answer2 Answer 2 state: CONFIRMED answerMode: ORDER SpotA_B2 Spot 1 isOffer: false action: KEEP SpotA_S2 Spot 1 isOffer false RequestStream->Request1 Request1->SpotA_B1 SpotB_B1 Spot 2 isOffer: true Request1->SpotB_B1 SpotC_B1 Spot 3 isOffer: true Request1->SpotC_B1 Request1->Answer1 Request2->Answer2 Request2->SpotA_B2 SpotB_B2 Spot 2 isOffer: false action: KEEP Request2->SpotB_B2 SpotC_B2 Spot 3 isOffer: false action: KEEP Request2->SpotC_B2 SpotB_S1 Spot 2 isOffer: true SpotC_S1 Spot 3 isOffer: true Answer2->SpotA_S2 SpotB_S2 Spot 2 isOffer false Answer2->SpotB_S2 SpotC_S2 Spot 3 isOffer false Answer2->SpotC_S2 Answer1->SpotB_S1 Answer1->SpotA_S1 Answer1->SpotC_S1

Warning Warnung:
Nach einer Buchung ist das Erstellen eines Request mit createOfferOnly=true bzw. mit RequestSpot, bei denen das Flag isOffer=true gesetzt ist, nicht mehr im selben RequestStream möglich.



Ablehnen eines Angebots

Angebote können abgelehnt werden. Hierzu wird ein neuer Request erstellt und im CreateRequestInput das Flag createOfferOnly=true gesetzt bzw. das Flag isOffer=true auf allen RequestSpots. Die RequestSpots müssen den AnswerSpots der letzten Answer entsprechen und daher folgt logisch, dass action=CANCEL auf allen RequestSpots beim Stornieren einer Answer gesetzt sein muss.

OfferRequest platzhalter_Reihe1_klein->platzhalter_Reihe4_klein RequestStream RequestStream platzhalter_Reihe1_klein->RequestStream Request1 Request 1 requestMode: OFFER Answer1 Answer 1 state: CONFIRMED answerMode: OFFER SpotA_B1 Spot 1 isOffer: true SpotA_S1 Spot 1 isOffer: true Request2 Request 2 requestMode: OFFER platzhalter_Reihe4_klein->Request2 Answer2 Answer 2 state: CONFIRMED answerMode: OFFER / ORDER SpotA_B2 Spot 1 isOffer: true action: CANCEL RequestStream->Request1 Request1->SpotA_B1 SpotB_B1 Spot 2 isOffer: true Request1->SpotB_B1 SpotC_B1 Spot 3 isOffer: true Request1->SpotC_B1 Request1->Answer1 Request2->Answer2 Request2->SpotA_B2 SpotB_B2 Spot 2 isOffer: true action: CANCEL Request2->SpotB_B2 SpotC_B2 Spot 3 isOffer: true action: CANCEL Request2->SpotC_B2 SpotB_S1 Spot 2 isOffer: true SpotC_S1 Spot 3 isOffer: true Answer1->SpotB_S1 Answer1->SpotA_S1 Answer1->SpotC_S1

Info Hinweis:
Hinweis: Gibt der Seller der Stornierung des Angebotes statt, so erstellt dieser eine Answer, die keine AnswerSpots enthält. In diesem Fall wird das Flag isOffer im CreateAnswerInput bedeutungslos und darf frei gewählt werden.



Buyer erfragt Angebot, erhält alternatives Angebot und nimmt es an

Erhält der Buyer vom Seller ein alternatives Angebot, so kann er dieses komplett annehmen und buchen (createOfferOnly / isOffer :false => requestMode-Wert = ORDER) oder aber Änderungen durchführen und so ein weiteres Angebot erfragen (createOfferOnly / isOffer :true => requestMode-Wert = OFFER). (siehe unten).

OfferRequest platzhalter_Reihe1_klein->platzhalter_Reihe4_klein RequestStream RequestStream platzhalter_Reihe1_klein->RequestStream Request1 Request 1 requestMode: OFFER Answer1 Answer 1 state: IS_ALTERNATIVE answerMode: OFFER SpotA_B1 Spot 1 isOffer: true SpotA_S1 Spot 1 isOffer: true Request2 Request 2 requestMode: ORDER platzhalter_Reihe4_klein->Request2 Answer2 Answer 2 state: CONFIRMED answerMode: ORDER SpotA_B2 Spot 1 isOffer: false action: KEEP SpotA_S2 Spot 1 isOffer false RequestStream->Request1 Request1->SpotA_B1 SpotB_B1 Spot 2 isOffer: true Request1->SpotB_B1 SpotC_B1 Spot 3 isOffer: true Request1->SpotC_B1 Request1->Answer1 Request2->Answer2 Request2->SpotA_B2 SpotB_B2 Spot 2 isOffer: false action: KEEP Request2->SpotB_B2 SpotC_B2 Spot X isOffer: false action: KEEP Request2->SpotC_B2 SpotB_S1 Spot 2 isOffer: true SpotC_S1 Spot X isOffer: true Answer2->SpotA_S2 SpotB_S2 Spot 2 isOffer false Answer2->SpotB_S2 SpotC_S2 Spot X isOffer false Answer2->SpotC_S2 Answer1->SpotB_S1 Answer1->SpotA_S1 Answer1->SpotC_S1



Ändern eines Angebotes

Möchte der Buyer das Angebot abändern, so muss ein neuer Request erstellt werden, der die neue Anfrage enthält. Hierbei muss wieder wahlweise das Flag createOfferOnly=true im CreateRequestInput gesetzt sein oder aber isOffer= true auf allen RequestSpots. Der requestMode-Wert im erstellten Request ist somit OFFER. Die entsprechende action, z.B. action=KEEP, um den reservierten Spot zu behalten, oder action=CANCEL, um den reservierten Spot zu stornieren, muss auf den RequestSpots ebenfalls gesetzt werden.

OfferRequest platzhalter_Reihe1_klein->platzhalter_Reihe4_klein RequestStream RequestStream platzhalter_Reihe1_klein->RequestStream Request1 Request 1 requestMode: OFFER Answer1 Answer 1 state: IS_ALTERNATIVE answerMode: OFFER SpotA_B1 Spot 1 isOffer: true SpotA_S1 Spot 1 isOffer: true Request2 Request 2 requestMode: OFFER platzhalter_Reihe4_klein->Request2 Answer2 Answer 2 state: CONFIRMED answerMode: OFFER SpotA_B2 Spot 1 isOffer: true action: CANCEL RequestStream->Request1 Request1->SpotA_B1 SpotB_B1 Spot 2 isOffer: true Request1->SpotB_B1 SpotC_B1 Spot 3 isOffer: true Request1->SpotC_B1 Request1->Answer1 Request2->Answer2 Request2->SpotA_B2 SpotB_B2 Spot 2 isOffer: true action: KEEP Request2->SpotB_B2 SpotC_B2 Spot X isOffer: true action: CANCEL Request2->SpotC_B2 SpotB_S1 Spot 2 isOffer: true SpotC_S1 Spot X isOffer: true SpotB_S2 Spot 2 isOffer: true Answer2->SpotB_S2 Answer1->SpotB_S1 Answer1->SpotA_S1 Answer1->SpotC_S1

Warning Warnung:
Ein Ändern des Angebotes kann nicht zusammen mit einer Buchung erfolgen!

Buyer fügt einen neuen Spot hinzu

Dieses Beispiel verdeutlicht noch einmal, dass eine Änderung des Angebots nicht zu einer Buchung führen darf, sondern immer erst ein neuer Request mit einer neuen Angebotsanforderung erstellt werden muss. (createOfferOnly / isOffer :true => requestMode-Wert = OFFER)
In diesem vorliegenden Fall lehnt der Buyer den alternativen Spot des Sellers ab und fügt eine eigene Alternative (Spot Y) mit der action:ADDITIONAL hinzu. Dies muss nun wiederum vom Seller mit einer Answer bestätigt werden.

OfferRequest platzhalter_Reihe1_klein->platzhalter_Reihe4_klein RequestStream RequestStream platzhalter_Reihe1_klein->RequestStream Request1 Request 1 requestMode: OFFER Answer1 Answer 1 state: IS_ALTERNATIVE answerMode: OFFER SpotA_B1 Spot 1 isOffer: true SpotA_S1 Spot 1 isOffer: true Request2 Request 2 requestMode: OFFER platzhalter_Reihe4_klein->Request2 Answer2 Answer 2 state: CONFIRMED answerMode: OFFER SpotA_B2 Spot 1 isOffer: true action: KEEP SpotA_S2 Spot 1 isOffer: true RequestStream->Request1 Request1->SpotA_B1 SpotB_B1 Spot 2 isOffer: true Request1->SpotB_B1 SpotC_B1 Spot 3 isOffer: true Request1->SpotC_B1 Request1->Answer1 Request2->Answer2 Request2->SpotA_B2 SpotB_B2 Spot 2 isOffer: true action: KEEP Request2->SpotB_B2 SpotC_B2 Spot X isOffer: true action: CANCEL Request2->SpotC_B2 SpotD_B2 Spot Y isOffer: true action: ADDITIONAL Request2->SpotD_B2 SpotB_S1 Spot 2 isOffer: true SpotC_S1 Spot X isOffer: true Answer2->SpotA_S2 SpotB_S2 Spot 2 isOffer: true Answer2->SpotB_S2 SpotC_S2 Spot Y isOffer: true Answer2->SpotC_S2 Answer1->SpotB_S1 Answer1->SpotA_S1 Answer1->SpotC_S1