Release notes

2023r9

Fix for amortizations with more than two decimals in rights API

Using the rights API, it is possible to create cost definitions with amortizations. Previously, creating nominal amortizations per run with values that had more than 2 decimals could result in the following error, even if the sum of the values would be the same as the amount.

  "errors": [
    {
      "errorCode": "RIGHTS-00017",
      "description": "$_The total amount of amortization values cannot be higher than the cost amount",
      "data": []
    }
  ]

This was because the values would be rounded off to two decimals in the database, for example 2820.306819 would be saved as 2820.31, causing inconsistencies.

From this version, when using the POST or PUT /costDefinitions call to create or update amortizations with values that have more than 2 decimals, the following error response will be returned:

{
"statusCode": "422",
"message": "Operation cannot be completed due to violations",
"timestamp": "2023-04-26T14:23:58Z",
"concept": "CostDefinition",
"id": "55555",
"errors": [
{
    "errorCode": "CORE-00002",
    "description": "Maximum 2 decimals are allowed",
    "data": [
        "30.777"
        ]
    }
  ]
}

The YAML of the rights API has been updated for this change.

2023r8

Additional contract restrictions in rights API

In several calls of the rights API, it is possible to define or retrieve information about exploitation rights and windows.

It was already possible to define blackout, maximum number of runs per unit and free rerun restrictions on those exploitation rights.

From this version, the following restrictions can also be defined:

  • Catch-up restriction

  • Overlapping episodes restriction

  • Manual validation restriction

  • Maximum planning period restriction

Consult the WHATS'ON Knowledge Base for more information about these restrictions.

This can be done in the following calls:

  • PUT /contracts/{contractId}

  • GET /contracts/{contractId}

  • POST /contracts

  • GET /contracts/{contractId}/contractEntries/{productId}

  • POST /contracts/{contractId}/contractEntries/{productId}

  • PUT /contracts/{contractId}/contractEntries/{productId}

  • GET /exploitationRights/{exploitationRightId}

Catch-up restriction

The catch-up restriction array consists of the following attributes:

  • runTypes: This is mandatory. Define the run type that the restriction applies to. This can be run and/or freeRerun.

  • runNumbers: Choose the run numbers of linear transmissions that the restriction applies to. This can be one or more individual run numbers and/or the value remainingRuns, which includes run numbers higher than 10 and bundled runs. If this is left empty, it will apply to any run or free rerun.

For example:

      "catchUpRestrictions": [
        {
          "runTypes": [
            "run",
          ],
          "runNumbers": [
            1,
            3,
            "remainingRuns"
          ]
        }
      ]

Overlapping episodes restriction

The restriction array consists of the following attributes:

  • fromDate: The start date of the restriction in format YYYY-MM-DD. If it is left empty, it applies from the start date of the right.

  • toDate: The end date of the restriction in format YYYY-MM-DD. If it is left empty, it ends on the end date of the right.

  • maxNumberOfEpisodes: This is mandatory and defines the maximum number of episodes of the same series that can be planned on an on-demand channel on the same day.

For example:

      "overlappingEpisodesRestrictions": [
        {
          "fromDate": "2019-01-01",
          "toDate": "2019-04-30",
          "maxNumberOfEpisodes": 0
        }
      ]

If it is defined in a POST or PUT call for a contract entry linked to a program or episode, an 422 error code is returned since it can only be created for series:

    "errorCode": "RIGHTS-00037",
    "description": "$_Product with external reference 648257527 must be a series to create an overlapping episode restriction",
     "data": []

Manual validation restriction

The restriction array consists of the following non-mandatory attributes:

  • fromDate: The start date of the restriction in format YYYY-MM-DD. If it is left empty, it applies from the start date of the right.

  • toDate: The end date of the restriction in format YYYY-MM-DD. If it is left empty, it ends on the end date of the right.

  • remarks

For example:

          "manualValidationRestrictions": [
            {
              "fromDate": "2019-01-01",
              "toDate": "2019-04-30",
              "remarks": "COMPLEX CONDITIONS"
            }
          ]

Maximum planning period restriction

The restriction array consists of the following mandatory attributes to define how long an exploitation right is valid after the first run:

  • number: Define the number of units.

  • unit: Define how the period should be measured. This can be hour, day, week, month, quarter or year.

For example:

          "maximumPlanningPeriodRestrictions": [
            {
              "number": 0,
              "unit": "day"
            }
          ]

The YAML of the rights API has been updated for these changes.

Start and end times of exploitation windows in rights API

In several calls of the rights API, it is possible to define or retrieve information about exploitation rights and windows.

Previously, it was only possible to define or retrieve the start and end dates of the windows.

For example:

 "exploitationWindows": [
        {
        "exploitationWindowId": "209393883",
        "startDateFormula": "string",
        "startDate": "2019-01-01",
        "endDateFormula": "string",
        "endDate": "2019-07-31",
        "remarks": "non-exclusive Spanish SAP",
        ...

However, this meant that the start and end time would always be empty when creating rights from the API.

From this version, it also possible to define and retrieve the start and end times of the windows. The following attributes were added to the exploitationWindows array:

  • startTimeFormula

  • endTimeFormula: These add a time formula to the window and should contain the abbreviation of the formula you want to use and the offset:

    • Start time of airing (relative): [SA] + 0h

    • End time of airing (relative): [EA] + 0m

    • Sport event: [SE] + 0s

  • startTime

  • endTime: These add an absolute time to the window and should be in the HH:MM format.

When I define null as value for the attributes, the start and end time of the exploitation window will be emptied.

If both the time and formula attributes are provided, the formulas will take precedence. Therefore, if a time should be defined, the formula attributes should be left out of the call.

For example, in the following case, the window will have Start time of airing (relative) as formula for its start and end time and not 15:30:

    "exploitationWindows": [ 
          { 
          "exploitationWindowId": "209393883",
          "startDateFormula": "string",
          "startDate": "2019-01-01",
          "endDateFormula": "string",
          "endDate": "2019-07-31",
          "startTimeFormula": "[SA] + 0h",
          "startTime": "15:30",
          "endTimeFormula": "[SA] + 0h",
          "endTime": "15:30",
          "remarks": "non-exclusive Spanish SAP",
           ...

These attributes were added in the following calls:

  • PUT /contracts/{contractId}

  • GET /contracts/{contractId}
  • POST /contracts
  • GET /contracts/{contractId}/contractEntries/{productId}
  • POST /contracts/{contractId}/contractEntries/{productId}
  • PUT /contracts/{contractId}/contractEntries/{productId}
  • GET /exploitationRights/{exploitationRightId}

The YAML of the rights API has been updated for these changes.

PUT call to update exchange rates in rights API

Previously, it was already possible to retrieve the possible values of the Currency drop-down list using the GET /currencies call of the rights API.

From this version, it also possible to update existing default exchange rates of those currencies using the new PUT /newExchangeRate call with URL. For example: /rights/v1/currencies/{currencyID}/newExchangeRate

The currencyID corresponds to the API reference of the currency for which you want to update the default exchange rate or currency conversion (RN-3104).

The body of the call contains the following mandatory attributes:

{
  "quotation": "1.01",
  "validFrom": "2023-08-01",
  "isDirectQuotation": "Yes"
}
  • quotation: The value of the exchange rate with multiple possible decimals.

  • validFrom: The date from which the exchange rate should apply in format [yyyy]-[mm]-[dd].

  • isDirectQuotation: Indicate whether the direct quotation should be updated (true) or the indirect quotation (false).

    • With the direct quotation, the exchange rate is defined as X local currency = 1 foreign currency. In the site preferences, you can define which quotation should be used by default (RN-3104).

    • The attribute should match the quotation of the site preference. For example, if isDirectQuotation is set to true and Indirect quotation is chosen in the site preferences, the following error is returned:

{
    "statusCode": "422",
    "message": "Operation cannot be completed due to violations",
    "timestamp": "2023-08-07T09:50:57Z",
    "concept": "Exchange rate",
    "id": "JPY",
    "errors": [
        {
            "errorCode": "RIGHTS-00032",
            "description": "$_Quotation type in the payload ('isDirectQuotation': true) is different than in site preferences 'Indirect quotation'",
            "data": [
                "true",
                "Indirect quotation"
            ]
        }
    ]
}

When an exchange rate has already been set on the date entered as validFrom date, the following error is returned:

    "errors": [
        {
            "errorCode": "RIGHTS-00034",
            "description": "The exchange rate has already been set for 2/08/23. \rYou cannot override this.",
            "data": []
        }
    ]

When the exchange rate is correctly updated, the following response is returned with the direct and indirect quotation:

{
    "statusCode": "200",
    "message": "Exchange rate has been modified",
    "timestamp": "2023-08-07T09:55:21Z",
    "concept": "Exchange rate",
    "id": "JPY",
    "exchangeRate": 0.9794319295,
    "reciprocalExchangeRate": 1.0210000000
}

The YAML of the API has been updated for this change.

Valid from date in GET /currencies call of rights API

It was already possible to retrieve the possible values of the Currency drop-down list using the GET /currencies call of the rights API. In a previous version, the current exchange rate value in direct and indirect quotation was already added to the response of the call (See version 2022r8).

From this version, the validFrom date of the current default exchange rate has also been added to the response.

    {
        "id": "GBP",
        "name": "GBP",
        "directQuotation": 1.1538017769,
        "indirectQuotation": 0.8667000000,
        "validFrom": "2022-03-05"
    }

Fix for linking parent series to contracts in rights API

Previously, when you would use a POST /contracts or /contracts/{contractId}/contractEntries/{productId} call and the productId in the body or URL referred to a parent series, the API service would crash and the following error was returned:

{
    "statusCode": "500",
    "message": "This message is not appropriate for this object",
    "timestamp": "2023-05-10T11:32:34Z"
}

This was because parent series cannot be linked to contract entries but the API could not handle this.

This issue has been fixed. From now on, a clearer error message is returned in this case:

{
    "statusCode": "422",
    "message": "Operation cannot be completed due to violations",
    "timestamp": "2023-07-07T08:34:08Z",
    "concept": "ContractEntry",
    "id": null,
    "errors": [
        {
            "errorCode": "RIGHTS-00038",
            "description": "$_Parent series with external reference 671568527 cannot be linked to a contract",
            "data": [
                "671568527"
            ]
        }
    ]
}

Fix for emptying number of runs using PUT or POST /contracts call in rights API

Previously, when

  • an exploitation right existed with 2 runs and 2 free reruns which were all linked to transmissions,

  • and a PUT or POST /contracts call was sent with a body that sets the number of runs to null, for example:

{
    "contractId": "640530000",
     ...
    "contractEntries": [
        {
            "productId": "145978527",
            "episodeIds": [
                "145994527"
            ],
            "exploitationRights": [
                {
                    "exploitationRightId": "673459005",
                    "productId": "145978527",
                    "episodeIds": [
                        "145994527"
                    ],
                    "exploitationRightType": "Free TV",
                    "status": null,
                    "numberOfRuns": {
                        "value": null,
                        "numberOfRunsCountType": "Count"
                    }
                   ...

the BAPI service would crash and return the following error:

{
    "statusCode": "500",
    "message": "Message not understood: #differenceFromSmallInteger:",
    "timestamp": "2023-05-10T17:37:00Z"
}

This was because the External number of runs field (RN-5109) is a formula field, which is not allowed to be empty.

This issue has been fixed. From now on, a 422 error message is returned:

{
    "statusCode": "422",
    "message": "Operation cannot be completed due to violations",
    "timestamp": "2023-05-12T13:41:10Z",
    "concept": "Contract",
    "id": "640530000",
    "errors": [
        {
            "errorCode": "CORE-00002",
            "description": "value cannot be null",
            "data": []
        }
    ]
}

Fix for number of runs in GET /contracts call of rights API

In a previous version, the External number of runs and External number of free reruns were introduced to allow an external right system to update the number of runs or free reruns using the BAPI, even if there is a run or free rerun linked to a transmission with a lower run number, which would require runs to be unlinked from the planning.

However, when

  • an exploitation right existed with runs and free reruns which were all linked to transmissions (for example, 2 runs and 2 free reruns);

  • a PUT /contracts call was sent that updated the number of runs and number of free reruns to 0;

  • and a GET /contracts call was done to retrieve details of the contract,

the numberOfRuns would be 2, which was incorrect. When the actual number of runs cannot be lowered, the External number of runs is set to 0 instead. In the GET /contracts call, the value of the external number of runs should then be returned (RN-5109). However, until now, for the numberOfRuns, the External number of runs would not be returned when it was empty or 0.

This issue has been fixed. In the GET /contracts call, the numberOfRuns will have the value of the External number of runs unless it is empty, then the Number of runs is returned.

2023r7

Generated contract numbers in rights API and model-based importer

It is now possible to automatically generate contract numbers. (RN-5713) Because the contract number is used in the rights API, the following calls have been adapted.

POST /contracts

If the contract number generation is set to Automatic,

  • and a contract number is provided in the payload (with value or null), a 422 error is returned:

   "errorCode": "RIGHTS-00038",
   "description": "The contract number cannot be changed as it is generated automatically.",
   "data": []
  • and the contract number is not provided, then WHATS'ON will create the contract with a generated number.

If the contract number generation is set to Manual,

  • and the contract number is missing in the payload or provided with a null value, then a 422 error is returned as the contract number is mandatory;

            "errorCode": "872",
            "description": "Please enter the field Contract number.",
            "data": [
                "Contract number"
  • and a contract number is provided, then the contract is created with that number.

PUT /contract

If the contract number generation is set to Automatic,

  • and a contract number is provided in the payload (with value or null), a 422 error is returned:

      "errorCode": "RIGHTS-00038"   
      "description": "The contract number cannot be changed as it is generated automatically.",
      "data": []
  • and the contract number is not provided, then it is left as it is.

If the contract number generation is set to Manual,

  • and the contract number is missing in the payload, the call is accepted.

  • and the contract number is provided with a null value, then a 422 error is returned as the contract number is mandatory;

     "errorCode": "872",
      "description": "Please enter the field Contract number.",
      "data": [
            "Contract number"
  • and a contract number is provided, then the contract is updated with that number.

Provisional dates in rights API

With the addition of the provisional dates on exploitation rights (RN-5680), the following attributes have been added to the GET /exploitationRights/{exploitationRightId} call of the rights API:

  • Provisional start date

  • Provisional start date

  • Start date accuracy

  • End date accuracy

When these fields have been entered on the window of the provided exploitation right, they are returned in the response body of the call.

For example:

     "provisionalStartDate": "2023-08-01",
     "provisionalEndDate": "2024-07-31",
     "startDateAccuracy": "Exact",
     "endDateAccuracy": "Exact"

A new version of the YAML is needed to be able to see these attributes.

2023r6

Fix for update run service records, available rights service and rights API service

Previously, update run service records were linked to broadcast right groups. When these broadcast right groups were removed, any linked records were also removed. This caused issues between the update run service and services that remove broadcast right groups at the same time, as service records were sometimes deleted at the same time.

This issue has been fixed. The hard link between the broadcast right group and the update run service records has been removed. Now, the records only have a reference to the OID of the broadcast right group, which ensures that the update run service records are not deleted when a broadcast right group is removed.

Furthermore, in certain cases, the rights API encountered multi-user errors, resulting in a "statusCode : 500" error with the message indicating: "Trying to delete 10 rows but deleted 0 instead."

The root cause was a conflict between the available rights service and the BAPI service, both of which attempted to remove broadcast right groups simultaneously, resulting in a conflict.

A fix was implemented to prevent the available rights service and the BAPI service from removing broadcast right groups simultaneously.