FD1 Client Protocol
 
Library Developer Home FD1 Client Protocol Home Concepts Reading Data Writing Data Protocol Defined Servers Connect & Authenticate Proxies & Tunnels
Webhooks & Firehoses Programming Support Logging Minor Facts State Facts Response Format How To Guides eCommerce Sites Custom Point of Sale Customer Access Bulk Downloads Major APIs / Endpoints All Endpoints Products Sales SalesBuilder Session Get Attribute Sale Capture General Purpose Data Capture Devices Barcode Scanners Eftpos IoT Sensors Power Outlets Printing Scales Security Cameras Purchasing / Supply Side Purchase Orders Invoices Invoice Payments Document Capture Rare APIs / Endpoints SSL Certificates API Key Management Diagnositics PosGreen Server to Client Messages Overview Resources / Objects Purchase Order Invoice Payable Invoice Payment Product Supplier Location Sale Lines Sale Delivery Details Sales Price Maps Employees Carriers Payments Product Kits Department 1 Customers

FD1 Get Attribute

The get Attribute group of functions allow you to retrieve a single value (attribute) for a single item.

SQL users: Get Attribute is similar to a multi table join selecting one field for a single record.

OO users: Get Attribute traverses objects to connected objects and can return any single property

Their power is that you can also navigate to related data and return an attribute from there. This makes them incredibly useful for web pages that might sometimes need an additional specific fact about a single product/customer/sale/etc Some examples to explain

fd1.products.get_product_attribute(description)
Returns the description for a single product (K arg required and not shown here)
fd1.products.get_product_attribute(barcode)
Returns the barcode for a single product. As products can have multiple barcodes, you can use a "selector" to retrieve them all
fd1.products.get_product_attribute(barcode[0])
fd1.products.get_product_attribute(barcode[1])
fd1.products.get_product_attribute(barcode[2])
fd1.products.get_product_attribute(barcode[1].physkey)
Returns the "physkey" field for the second barcode connected to the product you want

You can get quite deep with path traversal, as shown below (this is a conceptual example, it will not work)

fd1.products.get_product_attribute(last_sale[store=york].customer.email)
Finds the last sale of a product in the York store, selects the customer related to that sale and finally returns their email
Products--Barcodes
|--
Sales--Customers

products.get_product_attribute(want-string)

Want-String Format

Want strings have the generic format:

attribute[selector].attribute[selector]...{converter}/format-mask
where only the first attribute is required, all other parts are optional.

attribute is the name of the attribute (property/field) required. Essentially this is the name of the field where the data is stored

selector is an optional restriction where the attribute can have multiple values. If not provided, the first value is returned. "first" in this context varies by where/what resource is being used.

Where the requested attribute redirects to a related resource (eg sale -> customer), then you may repeat the process and request a specific attribute of that resource (eg a "customer" attribute). If you redirect to a related resource and do not provide an attribute, a default attribute will be provided.

Optional converters can be invoked to reprocess the value in someway. This is not currently implemented and reserved for future expansion

The final component is an optional format-mask, which requests the server to reformat the final return value in some way. A format-mask starts with a slash ( / ) followed by the mask definition. For example pretty printing, reformatting to various standards. Basically this saves clients from needing to format values. When a format mask is used, the output is typically a string so as to preserve formatting.

Consider fd1.sales.get_sale_attribute() as the initial call.
We are starting from a single "sale" resource, which is identified by the "k" query parameter

{
    a: "fd1.sales.get_sale_attribute(want-string)",
    k: 8451325
}
                
"a" value with want-stringResultExample result
fd1.sales.get_sale_attribute(completeddt) Extracts the completed date/time of the sale
{
  "rp": "27",
  "data": {
    "rows": [
      "23-may-2021 15:54"
    ]
  }
}
fd1.sales.get_sale_attribute(saletotal) Extracts the total value of the sale. This is formatted using whatever the FD1 servers determines is OK
{
  "rp": "27",
  "data": {
    "rows": [
      14.92
    ]
  }
}
fd1.sales.get_sale_attribute(saletotal/$[4]) Extracts the total value of the sale, but this time forces FD1 server to format as "money" to 4 decimal places
{
  "rp": "27",
  "data": {
    "rows": [
      "14.9200"
    ]
  }
}
fd1.sales.get_sale_attribute(customer) Extracts the customer, if any, connected to this sale. As no customer attribute was explicitly requested, FD1 selects a default attribute and returns that. Default attributes are typically name or description type information, so in this case the customer name is returned
{
  "rp": "27",
  "data": {
    "rows": [
      "John Smith"
    ]
  }
}
fd1.sales.get_sale_attribute(customer.email) john@gmail.com
fd1.sales.get_sale_attribute(customer.email{email.valid})

Selects the email of the customer on the sale and uses a converter to verify that it is a syntacitally valid address. (Converters are not yet available, example only)

{
  "rp": "27",
  "data": {
    "rows": [
      true
    ]
  }
}
fd1.sales.get_sale_attribute(customer.phone) 1234567
fd1.sales.get_sale_attribute(customer.phone/E.164) +61 3 123 4567
fd1.sales.get_sale_attribute()
fd1.sales.get_sale_attribute()
fd1.sales.get_sale_attribute()
fd1.sales.get_sale_attribute()