101 lines
3.1 KiB
Markdown
101 lines
3.1 KiB
Markdown
# `GET /article/search`
|
|
|
|
Protected. Requires a valid session cookie (`credentials: 'include'`).
|
|
|
|
Fuzzy article search against JTL-Wawi (MSSQL). Use this to build a search box / result list.
|
|
|
|
## Query parameters
|
|
|
|
| Param | Required | Description |
|
|
|-------|----------|-------------|
|
|
| `target` | yes | Search string. Split on spaces; each word must match (AND). Each word is matched with `LIKE %word%` against EAN, supplier article number, name, article number, or barcode. |
|
|
| `filter` | no | Comma-separated category IDs. Omit or leave empty to search all categories. See [Category filter](#category-filter). |
|
|
|
|
## Search behaviour
|
|
|
|
- Multiple spaces are collapsed to one.
|
|
- Example: `target=bizz allmix` → both `bizz` **and** `allmix` must match somewhere on the article.
|
|
- By default only **active** articles (`cAktiv = 'Y'`) are returned.
|
|
- Without a category filter, at most **2000** rows are returned.
|
|
- Results are ordered by product name ascending.
|
|
|
|
## Category filter
|
|
|
|
| `filter` value | Effect |
|
|
|----------------|--------|
|
|
| *(omitted or empty)* | All categories; `TOP 2000` |
|
|
| `751` | Include inactive articles (no `cAktiv = 'Y'` restriction). Still uses category branch logic if other IDs are present. |
|
|
| `16` or `16,39` | Restrict to articles in those categories (OR). No row limit. |
|
|
|
|
Pass category IDs as a comma-separated list: `filter=16,39`.
|
|
|
|
## Response `200`
|
|
|
|
```json
|
|
{
|
|
"katagg": {
|
|
"16": 12,
|
|
"39": 8
|
|
},
|
|
"recordset": [
|
|
{
|
|
"katList": "16,39",
|
|
"fVerfuegbar": 0,
|
|
"kArtikel": 49,
|
|
"fBestand": null,
|
|
"cArtNr": "42000044",
|
|
"cName": "BioBizz AllMix Peat Free 20L",
|
|
"fVKNEtto": 11.3445378151261,
|
|
"kSteuerklasse": 1
|
|
}
|
|
]
|
|
}
|
|
```
|
|
|
|
### `recordset[]` fields
|
|
|
|
| Field | Type | Notes |
|
|
|-------|------|-------|
|
|
| `kArtikel` | number | Internal article ID |
|
|
| `cArtNr` | string | Article number — pass to [`GET /article/get`](get.md) |
|
|
| `cName` | string | Display name |
|
|
| `fBestand` | number \| null | Stock in warehouse 1 |
|
|
| `fVerfuegbar` | number \| null | Available stock |
|
|
| `fVKNEtto` | number | Net sales price |
|
|
| `kSteuerklasse` | number | Tax class: `1` = 19%, `2` = 7%, `3` = 0% |
|
|
| `katList` | string \| null | Comma-separated category IDs on the article |
|
|
|
|
### `katagg`
|
|
|
|
Map of category ID → count of matching articles in that category (including parent categories in the tree). Use for category sidebar / facet counts.
|
|
|
|
### Display price (frontend)
|
|
|
|
Brutto VK is not returned; compute client-side using [`GET /misc/getSteuer`](../misc/getSteuer.md):
|
|
|
|
```js
|
|
function getBrutto(netto, kSteuerklasse, steuerklassen) {
|
|
const row = steuerklassen.find((s) => s.kSteuerklasse === kSteuerklasse);
|
|
if (!row) return null;
|
|
return netto * (1 + row.fSteuersatz / 100);
|
|
}
|
|
```
|
|
|
|
## Errors
|
|
|
|
| Status | Body |
|
|
|--------|------|
|
|
| 400 | `{ "error": "Query parameter \"target\" is required" }` |
|
|
| 401 | `{ "error": "Unauthorized" }` |
|
|
| 500 | `{ "error": "..." }` |
|
|
|
|
## Example
|
|
|
|
```js
|
|
const res = await fetch(
|
|
'http://localhost:4208/api/article/search?target=bizz%20allmix',
|
|
{ credentials: 'include' }
|
|
);
|
|
const { katagg, recordset } = await res.json();
|
|
```
|