From ccf7854e6cc94dd8e04e9fd843f8f82e2732524d Mon Sep 17 00:00:00 2001 From: seb Date: Sat, 22 Aug 2026 05:40:06 +0200 Subject: [PATCH] u --- .env.example | 2 ++ API.md | 4 +++- src/queries/product-list.js | 9 ++++++++- 3 files changed, 13 insertions(+), 2 deletions(-) diff --git a/.env.example b/.env.example index 108060a..4fb9647 100644 --- a/.env.example +++ b/.env.example @@ -26,6 +26,8 @@ LANGUAGE_ID=1 # Product sync (tSteuerzone.cName used to look up tax rates per tSteuerklasse) TAX_ZONE_NAME=Zone-EU +# Warehouse ID for inventory stock (vLagerbestandProLager) +WARENLAGER_ID=1 # Shop filter: active shop is queried from tShopSubshop at startup diff --git a/API.md b/API.md index 092da6b..1035b88 100644 --- a/API.md +++ b/API.md @@ -247,10 +247,12 @@ Notable fields: | `prices` | One entry per customer group | | `isCompositeProduct` | `"1"` if the article is a Stückliste parent | | `imghash` | Pass to `/v1/pimage?path=...` | +| `use_stock` | `"1"` if `cLagerAktiv = 'Y'`, otherwise `"0"` | +| `quantity` | Stock quantity from `dbo.vLagerbestandProLager` for configured `WARENLAGER_ID` | | Deposit fields | Present when JTL-POS Pfand attributes are set | | `attributes` | Article attributes from `tArtikelAttribut` (incl. Pfand) | -Many other product fields are filled with static defaults (`sort`, `use_stock`, `unit`, etc.) for JTL-POS compatibility. +Many other product fields are filled with static defaults (`sort`, `unit`, `PLU`, etc.) for JTL-POS compatibility. **Node only:** `prices[]` applies per–customer-group net overrides from `tPreis` / `tPreisDetail`. C++ currently fills every group with the base gross price. diff --git a/src/queries/product-list.js b/src/queries/product-list.js index 249ecdc..e3d8845 100644 --- a/src/queries/product-list.js +++ b/src/queries/product-list.js @@ -8,6 +8,7 @@ import { getActiveShopId } from '../shop.js'; const LANGUAGE_ID = Number(process.env.LANGUAGE_ID) || 1; const TAX_ZONE_NAME = process.env.TAX_ZONE_NAME || 'Zone-EU'; +const WARENLAGER_ID = Number(process.env.WARENLAGER_ID) || Number(process.env.JTL_KWARENLAGER) || 1; const PRODUCT_LIST_SQL = ` WITH TaxRates AS ( @@ -53,11 +54,14 @@ SELECT TOP (@limit) FROM Pos.vProductVariant pv WHERE pv.kProduct = a.kArtikel ) AS variantName, - a.cBarcode AS barcode + a.cBarcode AS barcode, + a.cLagerAktiv, + ISNULL(v.fBestand, 0) AS fBestand FROM dbo.tArtikel a INNER JOIN dbo.tArtikelBeschreibung ab ON ab.kArtikel = a.kArtikel AND ab.kSprache = @languageId LEFT JOIN TaxRates tr ON tr.kSteuerklasse = a.kSteuerklasse LEFT JOIN ImageRV ir ON ir.kArtikel = a.kArtikel +LEFT JOIN dbo.vLagerbestandProLager v ON v.kArtikel = a.kArtikel AND v.kWarenlager = @warenlagerId WHERE a.cAktiv = 'Y' AND (@kShop = 0 OR EXISTS ( SELECT 1 FROM dbo.tKategorieArtikel ka @@ -129,6 +133,7 @@ export async function getProductList({ cursor = 0, limit = 20 } = {}) { .input('languageId', sql.Int, LANGUAGE_ID) .input('taxZoneName', sql.NVarChar, TAX_ZONE_NAME) .input('kShop', sql.Int, getActiveShopId()) + .input('warenlagerId', sql.Int, WARENLAGER_ID) .query(PRODUCT_LIST_SQL), getCustomerGroupIds(), ]); @@ -209,6 +214,8 @@ export async function getProductList({ cursor = 0, limit = 20 } = {}) { variants: product.variantName ?? '', isCompositeProduct: product.isCompositeProduct, attributes: articleAttributes?.attributes ?? [], + use_stock: product.cLagerAktiv === 'Y' || product.cLagerAktiv === '1' ? '1' : '0', + quantity: String(product.fBestand ?? 0), ...(articleAttributes?.deposit ?? {}), }; });