/restaurant/product

This action can be used fetch product’s data of selected restaurant.

Generally, /restaurant/get is used to retrieve all data related to a restaurant. In some cases, particularly with lightweight websites, implementing local storage to store and handle data of returned by /restaurant/get is too much, this action can be used to fetch this data on demand.

Request structure

The structure is following:

POST nameValueRequired?
restaurant_idintegerYes
product_idintegerYes
ingredient_groupsbooleanNo

Response

{
  "id":"108340",

  "comment":"Id of ingredient group where thing X belongs to. All ingredient group are found from object ingredient_groups.",
  "group_id":"1",
  "name":"Vegetariana pizza",
  "description":"Sisään leivottu",
  "menu_number":"15.",
  "image":"http://pizzaonline.fi/convert/pizzanet2.php//tuotekuvat/",
  "comment":"Ids of ingredients that belong to this product.",
  "ingredients":[
    "48569",
    "48578",
    "48592",
    "48603"
  ],

  "comment":"List of ingredient ids that can be added to product. Added ingredients costs extra; see below for logic.",
  "addable_ingredients":[
    "48564",
    "48565",
    "..",
  ],
  "comment":"List of ingredients that customer can add to the product without any extra fee.",
  "addable_free_ingredients":[
    "53241",
    "48590",
    "48615"
  ],
  "comment":"List of ingredients that can be changed in this product. The group_id (“1” in this example) is ingredient_group_id where
  the ingredients can be changed from. Inside it is array of ingredients from ingredients which can be changed to this group.",
  "changeable_ingredients":{
    "1":[
      48569,
      48578,
      48592,
      48603
    ]
  },
  "comment":"Side dishes that customer can choose for this product. There should be exactly one side dish chosen if there is side dishes in this array.",
  "side_dishes":[
    {
      "id":"108324",
      "name":"7UP",
      "comment":"Size of the side dish. Same as variant’s “size”.",
      "size":"0.35 L"
    },
    {
      "id":"108327",
      "name":"Jaffa",
      "size":"0.35 L"
    }
  ],
  "comment":"Some restaurants, which allows lunch time prices to be used in online orders, may have side dishes that can only
  be applied at lunch time. For example a drink in addition to a pizza at lunch time.",
  "lunch_time_side_dishes":[
    {
      "id":"108324",
      "name":"7UP",
      "size":"0.35 L"
    },
    {
      "id":"108327",
      "name":"Jaffa",
      "size":"0.35 L"
    }
  ],
  "variants":[
    {
      "id":"108340",
      "size":"Norm.",
      "price":"5.90",

      "comment":"Product’s price when restaurant has lunch time. If lunch price is zero (0 or its variant),
      normal price should be used instead.",
      "lunch_price":"6.30",

      "comment":"price of the ingredient needs to be multiplied by this value to get correct ingredient price.",
      "ingredient_pricing_factor":"1.00",
      "comment":"Some ingredients may have hardcoded sum instead of factor. This is meant to be added on top of the ingredient price, after ingredient_pricing_factor. In practice always zero.",
      "ingredient_pricing_sum":0,
      "extras":[
        {
          "comment":"Id of this extra.",
          "id":"108816",
          "comment":"Id of the product where this extra belongs to. Can be ignored, shouldn’t be in the API at all.",
          "product_id":"108340",
          "name":"Extra valkosipuli",
          "comment":"Price customer needs to pay for adding this extra to the product. It may be zero. It’s viable to merge this to addable_ingredients and addable_free_ingredients, if you see that better than separate section.",
          "price":"1.00"
        }
      ]
    },
    ".. another variant .."
  ]
}

You can see example JSON here (without ingredient_groups).

Side dishes

There is attributes side_dishes and lunch_time_side_dishes which are used to specify side dishes choosable for a single restaurant. These are free to add for a product, but not required; if one does not want to have a drink with a pizza, the customer is free to choose not to. The client may or may not enforce customer to choose a side dish.

Handling ingredients

Details of ingredients are found in ingredient_groups determined by product’s group_id value. See below for information about ingredient groups.

Products can have several different types of ingredient data: ingredients, addable_ingredients, addable_free_ingredients, changeable_ingredienst and extras.

Due to fact that all products usually consists from different ingredients, though there is few products (mainly drinks) without any ingredients, our system enforces all clients to send all ingredients along the product id, to make it easier for client developers to catch errors related to this ingredient system. These ingredients are in ingredients array in product data.

For some product types, it is common that customer wants to add some additional ingredients to her product. For convenience, ids of these ingredients that can be added to this specific product can be found from addable_ingredients array. Actual ingredient data can be found from ingredient groups, fetchable using separate action or with ingredient_groups parameter in request, as explained below.

Costs of these additional ingredients are determined by ingredient_pricing_factor and ingredient_pricing_sum.

Some products may have some free ingredients which customer is free to add to the product. Commonly these contains ingredients like Oregano. These can be found at addable_free_ingredients array.

There is also extras, which also may contain ingredients like Oregano, or additional things like a flag to tell restaurant that customer wants double amount of meat to her kebab. These extras may either have extra cost or be free. In clients, these are often shown in separate section after other ingredients, but if it makes more sense in the client, the client can add them to addable_free_ingredients and/or addable_ingredients lists.

The main difference between ingredients and extras is that ingredients are per-product, but extras are per-variant, which makes it possible for each variant to have different extras in one product.

changeable_ingredients

Especially with pizzas, but with some other products too, customer may want to change some of the ingredients to another or remove it altogether. Since there is price considerations with ingredients, some restaurants don’t want to allow changing all the ingredients, there is separate list of ingredients that can be changed. There is also products which may contain more than one different types of ingredients, for example basic pizza ingredients and then separate sauce selection only for this current pizza, not for all of restaurant’s pizzas.

For example, there could be pizza called SpecialPizza, which has ingredients salad, Valitse sauce and foobar. salad and foobar would be ingredients that are in all of restaurant’s pizzas, so they’d reside in common pizza ingredient group, let’s say in ingredient group 1. But since this is special pizza which has secret ingredient of sauce, it resides in separate ingredient group. Data of these ingredients resides in special ingredient group called fantasia_ingredients, which means that the ingredient itself is not real ingredient, and needs to be changed to another ingredient.

So in changeable_ingredients in product’s data, there is hash of data with key being ingredient group id where client can get list of ingredients that can be changed to, and as value there is list of ingredients that can be changed to that group. There can be multiple groups, like in our example: ingredient group 1 for pizza ingredients, and for example 5703 for Valitse sauce. So there would be two arrays, one with 1 as key with two ingredients(salad and foobar) in it and one with 5703 as key with one ingredient(Valitse sauce).

For products which contains one or more fantasia ingredients, the fantasia ingredients must always be changed. For example, if product contains Valitse kastike and two other ingredients, the fantasia ingredient must be changed before the order will be accepted by the backend. Fantasia ingredients will also be present in the product’s ingredients array and also in changeable_ingredients array.

ingredient_groups

There is optional parameter ingredient_groups which, when set to true, will cause the action to return ingredient_groups in the response. Ingredients in these groups are ingredients only relevant to this product, even though they are structured as in /restaurant/ingredient_groups. Documentation for ingredient_groups is found from that action.

By default, this action contains only ingredient ids, which can be used to fetch the ingredients information from separate array. This way you’d only need to fetch the ingredient information once, so subsequent requests will be faster, but for websites, there would need to be internal caching so that the ingredient groups won’t be requested more than once.

If you decide to implement the caching, you may as well consider using /restaurant/get instead of split actions. In case you don’t wish to implement caching, you can set ingredient_groups to true to get only ingredients for specific product. This will be faster than calling /restaurant/ingredient_groups each time you need ingredients, but slower than the caching approach.

Details about ingredient groups can be found at /restaurant/ingredient_groups.

Expectable errors

See error conventions section for explanation how error system works.

Label Additional data Description
INVALID_PRODUCT_IDNoneDon’t try to give malformed id.
PRODUCT_NOT_FOUNDNoneIn case the product that was searched was not found from our system.