Skip to main content

Filtering records

What are the filtering options via the REST API?

Written by Petr Pech

Records in ABRA Flexi can be filtered. Values in filters can be either direct – supported variable types, record identifiers, or placeholders (e.g. now() or me()).

A list of supported attributes and their values (by type) can be obtained for each register in the field list.

Supported operators

Operator

Name

Description

Example

= or == or eq

Equality

Operator equals the value

a = 1

<> or != or ne or neq

Inequality

Operator does not equal the value

a != 1

< or lt

Less than

a < 1

<= or lte

Less than or equal to

a <= 1

> or gt

Greater than

a > 1

>= or gte

Greater than or equal to

a >= 1

like

Contains

The record contains the string

a like 'inStr'

like similar

Contains, ignoring diacritics

The record contains the string, ignoring diacritics

a like similar 'inStr'

between

Is within range

vek between 18 100

begins

Starts with

a begins 'Win'

begins similar

Starts with, ignoring diacritics

a begins similar 'Win'

ends

Ends with

a ends 'Strom'

in

Is one of the enumerated values

a in (1, 2, 3)

in subtree

Belongs to subtree

(see below)

in subtree 1

is true/false

Comparison of boolean values

a is true

is [not] null

Is (is not) filled in

a is null

is [not] empty

Is (is not) empty

not filled in, or is zero/false/an empty string

a is not empty

📝 Operators from the similar group only work correctly on ABRA Flexi with PostgreSQL 9.0 or newer. With an older database version, these operators do distinguish diacritics, i.e. they behave the same as operators without the similar keyword.

Operator

Name

Description

Example

and

Logical AND operator

Allows combining conditions

a = 1 and b = 1

or

Logical OR operator

Allows combining conditions

a = 1 or b = 1

not

Logical NOT operator

Negates the condition

not a = 1

( )

Parentheses

(a = 1 or b = 1) and (c = 2)

Operators have the usual precedence: the basic operators in the first table have the highest priority, then not, and, and the operator with the lowest priority is or. If you're unsure, use parentheses.

ℹ️ Negation can be written in two ways, and both return the same result — either with a negative operator, or by wrapping the condition in not(...):

/faktura-vydana/(typDokl.typDoklK not like 'typDokladu.dobropis') 
/faktura-vydana/(not(typDokl.typDoklK eq 'typDokladu.dobropis'))

Variable

Name

Description

Example

now()

Current date and time

Allows displaying records relative to the current date.

datSplat < now()

currentYear()

Current year

Allows displaying records relative to the current year.

platiDo <= currentYear()

me()

Logged-in user's name

Allows displaying records relative to the currently logged-in user.

uzivatel = me()

Filters must be properly encoded in the URL. When creating a filter manually, you can simply type it unencoded in the Firefox browser. When you then copy it to the clipboard, Firefox will encode it for you.

Writing values

In expressions such as a = 1, you can enter numbers, text strings, boolean values, date, and date+time. In addition, you can use the functions listed in the table above.

Numbers can be integers, -1 or 10, and decimals, 5.8 or -10.0.

Text strings can be enclosed in quotation marks, "abc", or apostrophes, 'abc'.

Boolean values are only true and false.

The date is entered in the format YYYY-MM-DD, e.g. 2011-11-01, and date and time in the format YYYY-MM-DD'T'HH:MM:SS[.sss], e.g. 2011-11-01T12:30:00. Not all notations allowed by ISO 8601 are supported — only these two (or three) shown here.

When referring to an object relation, any identifier can be used. Internal IDs are written as numbers (firma = 1), other identifiers as strings (firma = 'code:ABC').

Filtering by nested values

Some attributes used for filtering are actually relations. For example, issued invoices can be filtered by customer like this:

firma = 'code:FIRMA'

For these relations, dot notation can also be used to filter by their attributes; for example, you can filter issued invoices by the customer's group:

firma.skupFir = 'code:ODBĚRATEL-STANDARD'

There is no limit to the nesting depth.

⚠️ Negative operators (e.g. <>, !=) can be used with nested values, but they have one limitation: the filter will only match records where the related property is filled in. For example, with the filter /faktura-vydana/(typDokl.radaPrijem.kod!='FAKTURA-STANDARD'), the series is optional — so records that have the series filled in but with a different code value will be selected.

Filtering by tags

In addition to attributes, you can filter by tags in the same way (if tags are supported in the given register). For example, if you want to find all price list items tagged VIP, the filter would be:

stitky='code:VIP'

and the full URL would then be

/c/firma/cenik/(stitky='code:VIP').xml

Or if you want all items tagged VIP or DULEZITE, use:

stitky='code:VIP' or stitky='code:DULEZITE'

or

/c/firma/cenik/(stitky='code:VIP' or stitky='code:DULEZITE').xml

The and operator can be used the same way.

Filtering by subtree membership

Price list items are organized into a tree structure (it's possible that other registers may support tree structures in the future), and you can also filter by this organization. Consider the following price list tree:

Price list tree

  • Attached items (id = 2)

    • Category 1 (id = 3)

      • Category 1.1 (id = 4)

      • Category 1.2 (id = 5)

        • Category 1.2.1 (id = 6)

    • Category 2 (id = 7)

      • Category 2.1 (id = 8)

      • Category 2.2 (id = 9)

Unattached items (a virtual node under which the application displays items that are not part of the tree; you cannot filter within it)

This is how the tree is displayed in the application, but for the purposes of tree categorization of items, we consider Attached items to be the root. The IDs shown are for illustration only; if you're working with the tree via the REST API, it's recommended to use external identifiers.

On the price list (/c/firma/cenik), you can write a filter to get all items from Category 1 and all its subcategories (i.e. from the nodes Category 1, Category 1.1, Category 1.2, and Category 1.2.1) like this:

in subtree 3

which is actually a shorthand for

id in subtree 3

The full URL would look like this:

/c/firma/cenik/(in subtree 3)

If you need to get items only from a given node and not the entire subtree, you can use the nonrecursive modifier; for example, to get items only from Category 2, but not from Category 2.1 and Category 2.2, you can write

in subtree 7 nonrecursive 
/c/firma/cenik/(in subtree 7 nonrecursive)

As mentioned above, the notation in subtree 3 is shorthand for id in subtree 3, which is important when you need to filter other registers by price list subtree membership. For example, you can filter all stock cards for price list items from a certain subtree like this:

cenik in subtree 3 
/c/firma/skladova-karta/(cenik in subtree 3)

Filtering via relational properties

The filter allows any nesting depth except for properties that do not have a unique register. In other words, filtering is only possible in the case of a 1:1 relation.

/udalost/(zakazka.mistUrc.mesto = 'Praha')

If you need to filter within document items, you must filter directly in the items register:

/faktura-vydana-polozka/(doklFak=123 and cenik ="code:AUTO")


Default validity filter

All registers that have the platiOd and platiDo properties are, by default, filtered according to the current accounting period. For example, if one of your price lists has platiDo set to the value 2020, this price list will not appear in the cenik register if the current accounting period is 2021. This behavior can be overridden using the filtrovat-platnost parameter set to the value false.

The following example shows how to get price lists valid until 2020 within the current accounting period.

/c/firma/cenik/(platiDo = 2020).xml?filtrovat-platnost=false


User filters

The User filters register is used to save a filter. To create a filter, you need to work with the fields of the /filtr register.

Example of creating a filter with a selected tag value:

<winstrom version="1.0">
<filtr>
<nazev>Stitky filtr</nazev>
<kod>stitky</kod>
<beanKey>cz.winstrom.vo.cen.Cenik</beanKey>
<obsahFiltru>((stitky = 3))</obsahFiltru>
</filtr>
</winstrom>

Example of filtering a register using a saved filter:

/c/firma/cenik/(filter:2)

ℹ️ For a saved filter, you must use the internal ID.

Did this answer your question?