UnionInternationalCheminsdeFer / OSDM

Projects related to an open sales & distribution API for public transportation.
https://osdm.io
Apache License 2.0
53 stars 21 forks source link

Redesign Partial Refund Offer as Regular Refund Offer #354

Closed jspetrak closed 6 months ago

jspetrak commented 11 months ago

The partial refund should become part of the refund end-point by adding the additional parameters. The reply must support to exchange fulfillments.

TODO: proposal for adding the elements to RefundRequest and RefundReply. (Linus)

previous solution:

    /bookings/{bookingId}/partial-refund-offers:
    post:
      tags:
        - Exchange
      summary: Returns a partial refund offer for booking part(s) or passenger(s) to be removed. Operation is valid only if supported by underlying tariff.
      operationId: createPartialRefundOffersCollection
      parameters:
        - $ref: '#/components/parameters/requestor'
        - $ref: '#/components/parameters/acceptLanguage'
        - $ref: '#/components/parameters/traceParent'
        - $ref: '#/components/parameters/traceState'
        - $ref: '#/components/parameters/idempotencyKey'
        - name: bookingId
          in: path
          required: true
          schema:
            type: string
            nullable: false
        - name: embed
          in: query
          required: true
          schema:
            $ref: '#/components/schemas/ExchangeOfferCollectionResponseContent' 
      requestBody:
        required: true
        content:
          application/json:
            schema:
              $ref: '#/components/schemas/PartialRefundOfferRequest'
      responses:
        '200':
          description: |
            Partial refund offer found
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/PartialRefundOfferResponse'
          headers:
            Content-Language:
              schema:
                type: string
                description: |
                  The language of translatable strings in the response (see RFC2616-sec14.12).

        '400':
          $ref: '#/components/responses/BadRequestResponse'
        '401':
          $ref: '#/components/responses/UnauthorizedResponse'
        '403':
          $ref: '#/components/responses/ForbiddenResponse'
        '404':
          $ref: '#/components/responses/NotFoundResponse'
        '406':
          $ref: '#/components/responses/NotAcceptableResponse'
        '415':
          $ref: '#/components/responses/UnsupportedMediaTypeResponse'
        '500':
          $ref: '#/components/responses/InternalServerErrorResponse'
        '501':
          $ref: '#/components/responses/NotImplementedResponse'
        '503':
          $ref: '#/components/responses/ServiceUnavailableResponse'
        'default':
          $ref: '#/components/responses/DefaultErrorResponse'

    PartialRefundOfferRequest:
      type: object
      additionalProperties: false
      required:
        - bookingPartsToBeRefunded
      properties:
        overRuleCode:
          $ref: '#/components/schemas/OverruleCode'
        requestedFulfillmentOptions:
          type: array
          items:
            $ref: '#/components/schemas/FulfillmentOption'
        passengersToBeRemoved:
          type: array
          items:
            type: string
          nullable: true
        bookingPartsToBeRefunded:
          type: array
          items:
            type: string
          minItems: 1
          nullable: false
        refundDate:
          type: string
          format: date-time
          nullable: true

    PartialRefundOfferResponse:
      type: object
      additionalProperties: false
      properties:
        warnings:
          $ref: '#/components/schemas/WarningCollection'
        appliedOverruleCode:
          $ref: '#/components/schemas/OverruleCode'
        partialReundOffer:
          $ref: '#/components/schemas/ExchangeOffer'
        passengers:
          type: array
          items:
            $ref: '#/components/schemas/Passenger'
        trips:
          type: array
          items:
            $ref: '#/components/schemas/Trip'
CGantert345 commented 10 months ago

The partial refund adresses the use cases of refunding due to removed passegers (e.g. used in group bookings) and in refunding of booking parts (e.g. refunding a return trip).

The current refund implementation in OSDM does not implement these use cases as refunds, they are only possible as more complex exchange operation. The current refund design is related to refunding fulfilments which limits this functionality to eigther a full refund of a booking or to cases where a distributor uses individual fulfilment (which is only applied by a limited number of distributors).

A real partial refund implementation must therefore be based on refunding booking parts and passengers and will provide new fulfilmets if needed.

The current proposal therfore uses a request similar to the existing refund (no new trip) but with passengers and booking parts to be removed and a reply with a single exchange offer as the fulfilments need to be exchanged.

Linus-Turnit commented 10 months ago

image

    RefundOfferRequest:
      type: object
      additionalProperties: false
      description: |
        Request for a refund offer.
        Fulfillments can be provided in case the booking contains multiple individual fulfillments.
      required:
        - refundFulfillments
      properties:
        refundFulfillments:
          type: array
          items:
            $ref: '#/components/schemas/RefundFulfillment'
          minItems: 1
          nullable: false
        overruleCode:
          $ref: '#/components/schemas/OverruleCode'
        refundDate:
          description: |
            Indicates for passes the date taken as reference to compute possible partial refund. It is also the date taken
            as reference to invalidate the pass partially refunded.
          type: string
          format: date-time
          nullable: true

    RefundFulfillment:
      type: object
      required:
        - fulfillmentId
      properties:
        fulfillmentId:
          type: string
        bookingPartIds:
          description: Separate bookingParts in a fulfillment to be refunded.
          type: array
          items:
            type: string
        passengerIds:
          description: Used to refund individual passengers in a 'COLLECTIVE' fulfillment 
          type: array
          items: 
            type: string
jspetrak commented 10 months ago

RefundOfferRequest to retain the fulfillmentIds, PartialFulfillmentRefund structure to be optionally provided in case of trigerring the partial refund. If not supported, HTTP 501 is returned.

This way, the API is backward compatible.

In Refund Offer PATCH, the RefundOffer will have issuedFulfillments populated in case new fulfillments were produced during the partial refund.

Linus-Turnit commented 10 months ago

POST /bookings/{bookingId}/refund-offers

Request: image

    RefundOfferRequest:
      type: object
      additionalProperties: false
      description: |
        Request for a refund offer.
        Fulfillments can be provided in case the booking contains multiple individual fulfillments.
      required:
        - fulfillmentIds
      properties:
        fulfillmentIds:
          description: |
            id of the fulfillment to refund
          type: array
          items:
            type: string
          minItems: 1
          nullable: false
        partialRefundSpecs:
          description: |
            To do a partial refund repeat the fiulfillmentId and point out what to refund
          type: array
          items:
            $ref: '#/components/schemas/PartialRefundSpec'
        overruleCode:
          $ref: '#/components/schemas/OverruleCode'
        refundDate:
          description: |
            Indicates for passes the date taken as reference to compute possible partial refund. It is also the date taken
            as reference to invalidate the pass partially refunded.
          type: string
          format: date-time
          nullable: true
    PartialRefundSpec:
      type: object
      required:
        - fulfillmentId
      properties:
        fulfillmentId:
          description: |
            id of the fulfillment the part is related to
          type: string
        bookingPartIds:
          type: array
          items:
            type: string
        passengerIds:
          type: array
          items:
            type: string            

Response: image

'''

    RefundOffer:
      type: object
      additionalProperties: false
      required:
        - id
        - createdOn
        - validFrom
        - validUntil
        - status
        - fulfillments
        - refundFee
        - refundableAmount
      properties:
        id:
          description: |
            id of the refund offer
          type: string
          nullable: false
        summary:
          description: |
            A human-readable description of the refund offer.
          type: string
          nullable: true
          example: Refund Offer for Paris-Barcelona Andre Dupont 2022-07-23
        createdOn:
          type: string
          format: date-time
          nullable: false
        validFrom:
          type: string
          format: date-time
          nullable: false
        validUntil:
          description: |
             time until the offer can be used
          type: string
          format: date-time
          nullable: false
        confirmedOn:
          type: string
          format: date-time
          nullable: true
        status:
          $ref: '#/components/schemas/RefundStatus'
        reimbursementStatus:
          $ref: '#/components/schemas/ReimbursementStatus'
        reimbursementDateTime:
          type: string
          format: date-time
          nullable: true
        appliedOverruleCode:
          $ref: '#/components/schemas/OverruleCode'
        fulfillments:
          type: array
          items:
            $ref: '#/components/schemas/Fulfillment'
          minItems: 1
        issuedFulfillments:
          description: |
            New fulfillments after a partial refund
          type: array
          items:
            $ref: '#/components/schemas/Fulfillment'          
        issuedVouchers:
          type: array
          items:
            $ref: '#/components/schemas/VoucherInformation'
        refundFee:
          $ref: '#/components/schemas/Price'
          description: |
            Amount kept by the carrier and/or distributor
        refundableAmount:
          $ref: '#/components/schemas/Price'
          description: |
            Amount refunded to the purchaser
        refundOfferBreakdown:
          $ref: '#/components/schemas/RefundOfferItem'
        _links:
          description: |
            Java Property Name: 'links' 
          type: array
          items:
            $ref: '#/components/schemas/Link'
CGantert345 commented 10 months ago

Designed in Branch: https://github.com/UnionInternationalCheminsdeFer/OSDM/tree/partialRefund