GraphQL Ticket Lister Help

Hi, I’m creating a php-based kitchen display using GraphQL. I’m having trouble retrieving product tags. It doesn’t seem to be accessible from the API. I’m so confused about product tags, custom tags and order tags. Here is my query:

{
  getTickets(isClosed: false, orderBy: date) {
    id
    number
    tags {
      tag
      tagName
    }
    states {
      stateName
      state
    }
    orders {
      name
      portion
      quantity
      tags {
        tag
        tagName
      }
      priceTag
      states {
        stateName
        state
        stateValue
      }
    }
    entities {
      type
      name
    }
    note
  }
}

And here is the result:

{
  getTickets(isClosed: false, orderBy: date) {
    id
    number
    tags {
      tag
      tagName
    }
    states {
      stateName
      state
    }
    orders {
      name
      portion
      quantity
      tags {
        tag
        tagName
      }
      priceTag
      states {
        stateName
        state
        stateValue
      }
    }
    entities {
      type
      name
    }
    note
  }
}

You can see that there are no tags. I have created product tags indicating the type of item is is so it can be routed to either the bartender or back kitchen but I don’t know how to include that data in my query. Is it possible to do a subquery on each order item against getProduct?

Thanks for your help.

Here is a SS of my setup in Samba:

priceTag will return the product tag for the order (more than one product tag set for the item may return a comma delimited list - I’m not 100% sure, though)

This will return al products with related product tag(s) if set.

query{getProducts{name, portions{name, price}, tags{name, value}, groupCode, barcode}}

Other than that, you’ll want to pull the menu items’ custom tags into an associative array via SQL and check from there.

Hmm. It seems pretty limited. I went ahead and went through the painful process of installing sqlsrv driver for PHP. There seems to be no way to use getProducts with a range of productId’s. The only option is to do a getProduct query on each item in orders array. That would have to be done for each ticket displayed resulting in a ton of HTTP requests. Correct me if I’m wrong or is that the case?

The getProducts mutation returns all products.

{
  "data": {
    "getProducts": [
      {
        "id": 1,
        "name": "Toasted Bagel Jam",
        "portions": [
          {
            "name": "Normal",
            "price": 1.5
          }
        ],
        "tags": [
          {
            "name": "DiscountGroup",
            "value": "Emp"
          }
        ],
        "groupCode": "Breakfast",
        "barcode": null
      },
      {
        "id": 2,
        "name": "Toasted Bagel Cheese",
        "portions": [
          {
            "name": "Normal",
            "price": 2.25
          }
        ],
        "tags": [
          {
            "name": "DiscountGroup",
            "value": "Emp"
          }
        ],
        "groupCode": "Breakfast",
        "barcode": null
      },
...

Deserialise that into a class and either work with the class object, or fetch what data you need and create an associative array with productId as the key.

Not sure exactly the steps in PHP as the last time I did any meaningful work with PHP was over 10 years ago.

I left out id for the query, sorry. This should do:

query{getProducts{id, name, portions{name, price}, tags{name, value}, groupCode, barcode}}

Haha hey now. I’m too lazy to learn a new language lol. Anyway, after looking at the database, I see there’s no way to index custom tags in ‘MenuItems’ because they are stored as a JSON ojbect. So I’m using the ‘Tag’ field to separate into kitchen and bar items. Then I can just do SELECT * FROM MenuItems WHERE Tag='Kitchen'.

So there’s no way to limit the results this way with GraphQL? It seems like a waste of data transfer to request all products from the server. What if you had thousands of products?

It could be a hit to the db. But for a kitchen display, I would expect that data to be fetched once on startup and then maybe set some sort of refresh interval.

As for getting the custom tags here are some options:

  • Loop through the object and extract key/pair values for the tag
  • JSON query directly in the db
  • Use regex on the CustomTags string

I didn’t know I could do a JSON query in the db. I’m unfamiliar with SQL server. Could you give me an example against the MenuItems database?

Here is my MenuItems:

I don’t have any experience working with JSON within the db engine, so I have to turf this one to google.

Here’s how I’d do it with regex:

<?php

$customTags = '[{"TN":"OrderType","TV":"Pizza"},{"TN":"Combo","TV":"2 UNLTD 10,3 UNLTD 10"}]';
$tagName = 'OrderType';

$tagValue = getMenuItemCustomTagValue($customTags, $tagName);

//NULL OR EMPTY CHECK ON tagValue

//DO SOMETHING HERE


function getMenuItemCustomTagValue($customTagsJson, $tagName)
{
    $matchString = "\"TN\":\"$tagName\",\"TV\":\"([^\"]+)\"";

    if (preg_match("/$matchString/", $customTagsJson, $matches))
    {
        $tagValue = $matches[1];
        return $tagValue;
    }
    else
    {
        return ""; // OR RETURN NULL IF YOU PREFER
    }
}

OK, I’ll give that a shot. I might just use SQL to read data but I’ll use GraphQL for mutations like creating tickets and such. does Samba cache DB data or is everything realtime?

AFAIK SambaPOS caches most things and only reloads when commanded.

Here is an example of JSON in SQL. I use JSON to parse out specific things from PaymentData field in the Payments table for our USA card integration. The last portion of this report tag is assigning fields to the parsed data for a report.

{REPORT SQL DETAILS:SELECT
jsonData.[pdauth_code]
,jsonData.[pdCardHolderName]
,jsonData.[pdCardBrand]
,[Amount]
,[Date]
FROM [Payments] p

CROSS APPLY OPENJSON(p.[PaymentData])
-- this WITH portion allows explicit definition of the schema JSON Keys for output
-- and gives references to the columns/fields above in the SELECT portion
-- we can also use these as filters in the WHERE clause below
WITH (   
 pdTransactionID         varchar(1000) '$.TransactionID'
,pdauth_code        varchar(1000) '$.auth_code'
,pdCardHolderName        varchar(1000) '$.CardHolderName'
,pdCardBrand        varchar(1000) '$.CardBrand'
) jsonData
WHERE 1=1
AND [PaymentData]!=''
AND DATE > '{Start}'
AND DATE < '{End}'
ORDER BY [Date]
:F.Date
,F.pdauth_code
,F.pdCardHolderName
,F.pdCardBrand
,F.Amount
}
1 Like