Compare commits
3 Commits
7499fbc36e
...
c84a504a5c
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
c84a504a5c | ||
|
|
06d0dd3bb2 | ||
|
|
7286cd8bf2 |
@@ -140,17 +140,17 @@ Params: path values first, then `query:` and `body:` (`body?` = optional body).
|
|||||||
|
|
||||||
### Reusable types
|
### Reusable types
|
||||||
|
|
||||||
- `T1` = `{ id: int, number: str, type: str, entityId: int, date: str, lines: T20[], externalNumber?: str|null, createdAt?: str, shipping?: T19|null, shippings?: T19[], payment?: T30|null, payments?: T30[], paid?: bool, shipped?: bool, delivered?: bool, orderTotal?: num, paidTotal?: num, orderedQuantity?: num, shippedQuantity?: num, shipments?: T3[], files?: T9[] }`
|
- `T1` = `{ id: int, number: str, type: str, entityId: int, date: str, lines: T20[], externalNumber?: str|null, createdAt?: str, shipping?: T19|null, shippings?: T19[], payment?: T30|null, payments?: T30[], paid?: bool, shipped?: bool, delivered?: bool, orderTotal?: num, paidTotal?: num, orderedQuantity?: num, shippedQuantity?: num, shipments?: T3[], files?: T10[] }`
|
||||||
- `T2` = `{ id: int, sku: str, name: str, slug: str, desc: str|null, seo: str|null, track_stock: bool, unitamount: num|null, weight: num|null, unit: T27, brand: T26|null, categoryIds: int[], photos: T24[], eans: str[], prices: T35[], suppliers: T11[] }`
|
- `T2` = `{ id: int, sku: str, name: str, slug: str, desc: str|null, seo: str|null, track_stock: bool, unitamount: num|null, weight: num|null, unit: T27, brand: T26|null, categoryIds: int[], photos: T24[], eans: str[], prices: T35[], suppliers: T8[] }`
|
||||||
- `T3` = `{ id: int, number: str, type: str, date: str, lines: T20[], shippings: T19[], entityId?: int|null, externalNumber?: str|null, createdAt?: str|null, lineCount?: int, packageCount?: int, files?: T9[], state?: str }`
|
- `T3` = `{ id: int, number: str, type: str, date: str, lines: T20[], shippings: T19[], entityId?: int|null, externalNumber?: str|null, createdAt?: str|null, lineCount?: int, packageCount?: int, files?: T10[], state?: str }`
|
||||||
- `T4` = `{ id: int, number: str, type: str, date: str, lines: T20[], entityId?: int|null, externalNumber?: str|null, createdAt?: str, positions?: int, grossTotal?: num, totalQuantity?: num, customerName?: str|null, files?: T9[] }`
|
- `T4` = `{ id: int, number: str, type: str, date: str, lines: T20[], entityId?: int|null, externalNumber?: str|null, createdAt?: str, positions?: int, grossTotal?: num, totalQuantity?: num, customerName?: str|null, files?: T10[] }`
|
||||||
- `T5` = `{ id: int, number: str, type: str, supplierId: int, date: str, lines: T20[], files: T9[], externalNumber?: str|null, createdAt?: str, ledger?: T39 }`
|
- `T5` = `{ id: int, number: str, type: str, supplierId: int, date: str, lines: T20[], files: T10[], externalNumber?: str|null, createdAt?: str, ledger?: T39 }`
|
||||||
- `T6` = `{ name: str, path: str, totalSizeBytes: int, timestamp: str|null, manifest?: T7|null }`
|
- `T6` = `{ name: str, path: str, totalSizeBytes: int, timestamp: str|null, manifest?: T7|null }`
|
||||||
- `T7` = `{ id: str, timestamp: str, dateKey: str, monthKey: str, dbProvider: str, files: T12, totalSizeBytes: int, durationMs: int }`
|
- `T7` = `{ id: str, timestamp: str, dateKey: str, monthKey: str, dbProvider: str, files: T12, totalSizeBytes: int, durationMs: int }`
|
||||||
- `T8` = `{ id: int, name: str, width: num, height: num, dpi: int, type: str, content: { objects: T21[] }, thumb?: str|null }`
|
- `T8` = `{ id: int, articleId: int, entityId: int, pu: num, sort: int, supplierName?: str|null, sku?: str|null, stock?: num|null, priceId?: int|null, price?: T41|null, incoming?: { date: str, amount: num }[] }`
|
||||||
- `T9` = `{ id: int, manifestId: int, fileId: int, sort: int, hash: str, mimetype: str, name: str, size: int, created?: str, modified?: str, skeledash?: str|null, thumbx?: int|null, thumby?: int|null, meta?: { [k]: str }|null }`
|
- `T9` = `{ id: int, name: str, width: num, height: num, dpi: int, type: str, content: { objects: T21[] }, thumb?: str|null }`
|
||||||
- `T10` = `{ id: int, name: str, pairingpin?: str|null, token?: str|null, pairedAt?: str|null, clientserial?: str|null, rootCategoryId?: int|null, syncRootArticles?: bool, lastseenAt?: str|null, updatedAt?: str|null, categoryIds?: int[] }`
|
- `T10` = `{ id: int, manifestId: int, fileId: int, sort: int, hash: str, mimetype: str, name: str, size: int, created?: str, modified?: str, skeledash?: str|null, thumbx?: int|null, thumby?: int|null, meta?: { [k]: str }|null }`
|
||||||
- `T11` = `{ id: int, articleId: int, entityId: int, pu: num, sort: int, supplierName?: str|null, sku?: str|null, stock?: num|null, priceId?: int|null, price?: T41|null }`
|
- `T11` = `{ id: int, name: str, pairingpin?: str|null, token?: str|null, pairedAt?: str|null, clientserial?: str|null, rootCategoryId?: int|null, syncRootArticles?: bool, lastseenAt?: str|null, updatedAt?: str|null, categoryIds?: int[] }`
|
||||||
- `T12` = `{ vfs: T40, storage: T40, database: T33 }`
|
- `T12` = `{ vfs: T40, storage: T40, database: T33 }`
|
||||||
- `T13` = `{ id: int, entityId: int, addressType: str, firstName?: str|null, name?: str|null, street?: str|null, streetNumber?: str|null, zip?: str|null, city?: str|null, county?: str|null }`
|
- `T13` = `{ id: int, entityId: int, addressType: str, firstName?: str|null, name?: str|null, street?: str|null, streetNumber?: str|null, zip?: str|null, city?: str|null, county?: str|null }`
|
||||||
- `T14` = `{ id: int, company_id: int, prompt: str, max_itr: int, cron: str, created_at: str, desc?: str|null, skills?: str|null, lastagentnote?: str|null, lastrun_at?: str|null }`
|
- `T14` = `{ id: int, company_id: int, prompt: str, max_itr: int, cron: str, created_at: str, desc?: str|null, skills?: str|null, lastagentnote?: str|null, lastrun_at?: str|null }`
|
||||||
@@ -297,10 +297,10 @@ _none_
|
|||||||
- Returns: `200 { ok: bool }`
|
- Returns: `200 { ok: bool }`
|
||||||
#### List article suppliers — `GET /article/{sku}/supplier`
|
#### List article suppliers — `GET /article/{sku}/supplier`
|
||||||
- Params: `sku: str`
|
- Params: `sku: str`
|
||||||
- Returns: `200 { suppliers: T11[] }`
|
- Returns: `200 { suppliers: T8[] }`
|
||||||
#### Assign supplier to article — `POST /article/{sku}/supplier`
|
#### Assign supplier to article — `POST /article/{sku}/supplier`
|
||||||
- Params: `sku: str, body: { entityId: int, sku?: str|null, pu?: num, stock?: num|null, sort?: int|null, netPrice?: num|null, taxId?: int|null, taxRate?: num|null }`
|
- Params: `sku: str, body: { entityId: int, sku?: str|null, pu?: num, stock?: num|null, sort?: int|null, netPrice?: num|null, taxId?: int|null, taxRate?: num|null }`
|
||||||
- Returns: `201 { supplier: T11 }`
|
- Returns: `201 { supplier: T8 }`
|
||||||
#### Reorder article suppliers — `PUT /article/{sku}/supplier/order`
|
#### Reorder article suppliers — `PUT /article/{sku}/supplier/order`
|
||||||
- Params: `sku: str, body: { ids: int[] }`
|
- Params: `sku: str, body: { ids: int[] }`
|
||||||
- Returns: `200 { ids: int[] }`
|
- Returns: `200 { ids: int[] }`
|
||||||
@@ -309,7 +309,7 @@ _none_
|
|||||||
- Returns: `204 void`
|
- Returns: `204 void`
|
||||||
#### Update article supplier assignment — `PATCH /article/{sku}/supplier/{id}`
|
#### Update article supplier assignment — `PATCH /article/{sku}/supplier/{id}`
|
||||||
- Params: `sku: str, id: int, body: { sku?: str|null, pu?: num, stock?: num|null, sort?: int, netPrice?: num|null, taxId?: int|null, taxRate?: num|null }`
|
- Params: `sku: str, id: int, body: { sku?: str|null, pu?: num, stock?: num|null, sort?: int, netPrice?: num|null, taxId?: int|null, taxRate?: num|null }`
|
||||||
- Returns: `200 { supplier: T11 }`
|
- Returns: `200 { supplier: T8 }`
|
||||||
#### Set article track_stock flag by SKU — `PUT /article/{sku}/track_stock`
|
#### Set article track_stock flag by SKU — `PUT /article/{sku}/track_stock`
|
||||||
- Params: `sku: str, body: { track_stock: bool }`
|
- Params: `sku: str, body: { track_stock: bool }`
|
||||||
- Returns: `200 { article: T2 }`
|
- Returns: `200 { article: T2 }`
|
||||||
@@ -555,7 +555,7 @@ _none_
|
|||||||
- Returns: `200 str`
|
- Returns: `200 str`
|
||||||
#### Generate and attach delivery note PDF (goods receipt) — `POST /delivery/{id}/pdf`
|
#### Generate and attach delivery note PDF (goods receipt) — `POST /delivery/{id}/pdf`
|
||||||
- Params: `id: int`
|
- Params: `id: int`
|
||||||
- Returns: `201 { attachment: T9, fileUrl: str }`
|
- Returns: `201 { attachment: T10, fileUrl: str }`
|
||||||
|
|
||||||
### Section: /entity
|
### Section: /entity
|
||||||
|
|
||||||
@@ -646,19 +646,19 @@ _none_
|
|||||||
- Returns: `200 { labeltemplates: { id: int, name: str, width: num, height: num, dpi: int, type: str, thumb?: str|null }[] }`
|
- Returns: `200 { labeltemplates: { id: int, name: str, width: num, height: num, dpi: int, type: str, thumb?: str|null }[] }`
|
||||||
#### Create label template — `POST /labeltemplate`
|
#### Create label template — `POST /labeltemplate`
|
||||||
- Params: `body: { name: str, width: num, height: num, dpi: int, type: str, content: { objects: T21[] } }`
|
- Params: `body: { name: str, width: num, height: num, dpi: int, type: str, content: { objects: T21[] } }`
|
||||||
- Returns: `201 { labeltemplate: T8 }`
|
- Returns: `201 { labeltemplate: T9 }`
|
||||||
#### Delete label template — `DELETE /labeltemplate/{id}`
|
#### Delete label template — `DELETE /labeltemplate/{id}`
|
||||||
- Params: `id: int`
|
- Params: `id: int`
|
||||||
- Returns: `204 void`
|
- Returns: `204 void`
|
||||||
#### Get label template by ID — `GET /labeltemplate/{id}`
|
#### Get label template by ID — `GET /labeltemplate/{id}`
|
||||||
- Params: `id: int`
|
- Params: `id: int`
|
||||||
- Returns: `200 { labeltemplate: T8 }`
|
- Returns: `200 { labeltemplate: T9 }`
|
||||||
#### Update label template (partial) — `PATCH /labeltemplate/{id}`
|
#### Update label template (partial) — `PATCH /labeltemplate/{id}`
|
||||||
- Params: `id: int, body: { name?: str, width?: num, height?: num, dpi?: int, type?: str, content?: { objects: T21[] } }`
|
- Params: `id: int, body: { name?: str, width?: num, height?: num, dpi?: int, type?: str, content?: { objects: T21[] } }`
|
||||||
- Returns: `200 { labeltemplate: T8 }`
|
- Returns: `200 { labeltemplate: T9 }`
|
||||||
#### Update label template — `PUT /labeltemplate/{id}`
|
#### Update label template — `PUT /labeltemplate/{id}`
|
||||||
- Params: `id: int, body: { name?: str, width?: num, height?: num, dpi?: int, type?: str, content?: { objects: T21[] } }`
|
- Params: `id: int, body: { name?: str, width?: num, height?: num, dpi?: int, type?: str, content?: { objects: T21[] } }`
|
||||||
- Returns: `200 { labeltemplate: T8 }`
|
- Returns: `200 { labeltemplate: T9 }`
|
||||||
|
|
||||||
### Section: /ledger
|
### Section: /ledger
|
||||||
|
|
||||||
@@ -778,7 +778,7 @@ _none_
|
|||||||
- Returns: `201 { payment: T30 }`
|
- Returns: `201 { payment: T30 }`
|
||||||
#### Generate and attach order PDF — `POST /order/{id}/pdf`
|
#### Generate and attach order PDF — `POST /order/{id}/pdf`
|
||||||
- Params: `id: int`
|
- Params: `id: int`
|
||||||
- Returns: `201 { attachment: T9, fileUrl: str }`
|
- Returns: `201 { attachment: T10, fileUrl: str }`
|
||||||
#### List shipments of an order — `GET /order/{id}/shipment`
|
#### List shipments of an order — `GET /order/{id}/shipment`
|
||||||
- Params: `id: int`
|
- Params: `id: int`
|
||||||
- Returns: `200 { shipments: T3[] }`
|
- Returns: `200 { shipments: T3[] }`
|
||||||
@@ -808,16 +808,16 @@ _none_
|
|||||||
|
|
||||||
#### List POS terminals — `GET /posterminal`
|
#### List POS terminals — `GET /posterminal`
|
||||||
_none_
|
_none_
|
||||||
- Returns: `200 { posterminals: T10[] }`
|
- Returns: `200 { posterminals: T11[] }`
|
||||||
#### Create POS terminal — `PUT /posterminal`
|
#### Create POS terminal — `PUT /posterminal`
|
||||||
- Params: `body: { name: str, rootCategoryId?: int|null, syncRootArticles?: bool }`
|
- Params: `body: { name: str, rootCategoryId?: int|null, syncRootArticles?: bool }`
|
||||||
- Returns: `200 { posterminal: T10 }`
|
- Returns: `200 { posterminal: T11 }`
|
||||||
#### Delete POS terminal — `DELETE /posterminal/{id}`
|
#### Delete POS terminal — `DELETE /posterminal/{id}`
|
||||||
- Params: `id: int`
|
- Params: `id: int`
|
||||||
- Returns: `204 void`
|
- Returns: `204 void`
|
||||||
#### Update POS terminal — `PATCH /posterminal/{id}`
|
#### Update POS terminal — `PATCH /posterminal/{id}`
|
||||||
- Params: `id: int, body: { name?: str, rootCategoryId?: int|null, syncRootArticles?: bool, pairingpin?: str|null }`
|
- Params: `id: int, body: { name?: str, rootCategoryId?: int|null, syncRootArticles?: bool, pairingpin?: str|null }`
|
||||||
- Returns: `200 { posterminal: T10 }`
|
- Returns: `200 { posterminal: T11 }`
|
||||||
#### Disable all categories on terminal — `DELETE /posterminal/{id}/all`
|
#### Disable all categories on terminal — `DELETE /posterminal/{id}/all`
|
||||||
- Params: `id: int`
|
- Params: `id: int`
|
||||||
- Returns: `200 { id: int, categoryIds: int[] }`
|
- Returns: `200 { id: int, categoryIds: int[] }`
|
||||||
@@ -916,7 +916,7 @@ _none_
|
|||||||
- Returns: `201 { order: T1 }`
|
- Returns: `201 { order: T1 }`
|
||||||
#### Generate and attach quote PDF — `POST /quote/{id}/pdf`
|
#### Generate and attach quote PDF — `POST /quote/{id}/pdf`
|
||||||
- Params: `id: int`
|
- Params: `id: int`
|
||||||
- Returns: `201 { attachment: T9, fileUrl: str }`
|
- Returns: `201 { attachment: T10, fileUrl: str }`
|
||||||
|
|
||||||
### Section: /serper
|
### Section: /serper
|
||||||
|
|
||||||
@@ -955,7 +955,7 @@ _none_
|
|||||||
- Returns: `200 str`
|
- Returns: `200 str`
|
||||||
#### Generate and attach shipment PDF (delivery note) — `POST /shipment/{id}/pdf`
|
#### Generate and attach shipment PDF (delivery note) — `POST /shipment/{id}/pdf`
|
||||||
- Params: `id: int`
|
- Params: `id: int`
|
||||||
- Returns: `201 { attachment: T9, fileUrl: str }`
|
- Returns: `201 { attachment: T10, fileUrl: str }`
|
||||||
#### List packages of a shipment — `GET /shipment/{id}/shipping`
|
#### List packages of a shipment — `GET /shipment/{id}/shipping`
|
||||||
- Params: `id: int`
|
- Params: `id: int`
|
||||||
- Returns: `200 { shippings: T19[] }`
|
- Returns: `200 { shippings: T19[] }`
|
||||||
@@ -1030,10 +1030,10 @@ _none_
|
|||||||
- Returns: `200 { supplier: T38 }`
|
- Returns: `200 { supplier: T38 }`
|
||||||
#### List supplier articles by SKUs — `GET /supplier/{id}/articles`
|
#### List supplier articles by SKUs — `GET /supplier/{id}/articles`
|
||||||
- Params: `id: int, query: skus?: str`
|
- Params: `id: int, query: skus?: str`
|
||||||
- Returns: `200 { articles: { id: int, articleId: int, entityId: int, pu: num, sort: int, article: { id: int, sku: str, name?: str|null, slug?: str|null, photos?: { sort: int, fullHash: str, thumbW: int, thumbH: int, thumbHash: str }[], eans?: str[] }, supplierName?: str|null, sku?: str|null, stock?: num|null, priceId?: int|null, price?: T41|null }[] }`
|
- Returns: `200 { articles: { id: int, articleId: int, entityId: int, pu: num, sort: int, article: { id: int, sku: str, name?: str|null, slug?: str|null, photos?: { sort: int, fullHash: str, thumbW: int, thumbH: int, thumbHash: str }[], eans?: str[] }, supplierName?: str|null, sku?: str|null, stock?: num|null, priceId?: int|null, price?: T41|null, incoming?: { date: str, amount: num }[] }[] }`
|
||||||
#### Query supplier articles by SKUs (bulk) — `POST /supplier/{id}/articles`
|
#### Query supplier articles by SKUs (bulk) — `POST /supplier/{id}/articles`
|
||||||
- Params: `id: int, body?: { skus?: str[] }`
|
- Params: `id: int, body?: { skus?: str[] }`
|
||||||
- Returns: `200 { articles: { id: int, articleId: int, entityId: int, pu: num, sort: int, article: { id: int, sku: str, name?: str|null, slug?: str|null, photos?: { sort: int, fullHash: str, thumbW: int, thumbH: int, thumbHash: str }[], eans?: str[] }, supplierName?: str|null, sku?: str|null, stock?: num|null, priceId?: int|null, price?: T41|null }[] }`
|
- Returns: `200 { articles: { id: int, articleId: int, entityId: int, pu: num, sort: int, article: { id: int, sku: str, name?: str|null, slug?: str|null, photos?: { sort: int, fullHash: str, thumbW: int, thumbH: int, thumbHash: str }[], eans?: str[] }, supplierName?: str|null, sku?: str|null, stock?: num|null, priceId?: int|null, price?: T41|null, incoming?: { date: str, amount: num }[] }[] }`
|
||||||
|
|
||||||
### Section: /thumb
|
### Section: /thumb
|
||||||
|
|
||||||
|
|||||||
@@ -3,6 +3,7 @@ import Box from '@mui/material/Box';
|
|||||||
import Typography from '@mui/material/Typography';
|
import Typography from '@mui/material/Typography';
|
||||||
import WarehouseIcon from '@mui/icons-material/Warehouse';
|
import WarehouseIcon from '@mui/icons-material/Warehouse';
|
||||||
import EditOutlinedIcon from '@mui/icons-material/EditOutlined';
|
import EditOutlinedIcon from '@mui/icons-material/EditOutlined';
|
||||||
|
import LocalShippingOutlinedIcon from '@mui/icons-material/LocalShippingOutlined';
|
||||||
import Tooltip from '@mui/material/Tooltip';
|
import Tooltip from '@mui/material/Tooltip';
|
||||||
import { PanelTile } from 'dashgui/panels';
|
import { PanelTile } from 'dashgui/panels';
|
||||||
import { formatStock } from '../searchFormat';
|
import { formatStock } from '../searchFormat';
|
||||||
@@ -18,6 +19,83 @@ import {
|
|||||||
|
|
||||||
const SECOND_ROW_MIN_HEIGHT = 220;
|
const SECOND_ROW_MIN_HEIGHT = 220;
|
||||||
|
|
||||||
|
function formatDate(iso) {
|
||||||
|
if (!iso) return '';
|
||||||
|
const d = new Date(iso);
|
||||||
|
if (Number.isNaN(d.getTime())) return String(iso);
|
||||||
|
return d.toLocaleDateString('de-DE');
|
||||||
|
}
|
||||||
|
|
||||||
|
function extractIncoming(articleData, isParent) {
|
||||||
|
const items = [];
|
||||||
|
|
||||||
|
const collect = (article, variantInfo = null) => {
|
||||||
|
if (!article) return;
|
||||||
|
|
||||||
|
if (Array.isArray(article.incoming)) {
|
||||||
|
for (const inc of article.incoming) {
|
||||||
|
const amount = Number(inc?.amount) || 0;
|
||||||
|
if (amount > 0) {
|
||||||
|
items.push({
|
||||||
|
date: inc.date || null,
|
||||||
|
amount,
|
||||||
|
supplierName: inc.supplierName || null,
|
||||||
|
supplierSku: inc.sku || null,
|
||||||
|
pu: inc.pu || null,
|
||||||
|
variantSku: variantInfo?.sku || null,
|
||||||
|
variantName: variantInfo?.name || null,
|
||||||
|
});
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (Array.isArray(article.suppliers)) {
|
||||||
|
for (const sup of article.suppliers) {
|
||||||
|
if (Array.isArray(sup?.incoming)) {
|
||||||
|
for (const inc of sup.incoming) {
|
||||||
|
const amount = Number(inc?.amount) || 0;
|
||||||
|
if (amount > 0) {
|
||||||
|
items.push({
|
||||||
|
date: inc.date || null,
|
||||||
|
amount,
|
||||||
|
supplierName: sup.supplierName || null,
|
||||||
|
supplierSku: sup.sku || null,
|
||||||
|
pu: sup.pu || null,
|
||||||
|
variantSku: variantInfo?.sku || null,
|
||||||
|
variantName: variantInfo?.name || null,
|
||||||
|
});
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
collect(articleData);
|
||||||
|
|
||||||
|
if (isParent) {
|
||||||
|
const children = Array.isArray(articleData?.children) ? articleData.children : [];
|
||||||
|
for (const child of children) {
|
||||||
|
const fullChild = getArticle(child.sku) || child;
|
||||||
|
collect(fullChild, {
|
||||||
|
sku: fullChild.sku || child.sku,
|
||||||
|
name: fullChild.name || child.name,
|
||||||
|
});
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
items.sort((a, b) => {
|
||||||
|
if (a.date && b.date) {
|
||||||
|
return new Date(a.date).getTime() - new Date(b.date).getTime();
|
||||||
|
}
|
||||||
|
if (a.date) return -1;
|
||||||
|
if (b.date) return 1;
|
||||||
|
return 0;
|
||||||
|
});
|
||||||
|
|
||||||
|
return items;
|
||||||
|
}
|
||||||
|
|
||||||
export default class ArticleViewStock extends PureComponent {
|
export default class ArticleViewStock extends PureComponent {
|
||||||
constructor(props) {
|
constructor(props) {
|
||||||
super(props);
|
super(props);
|
||||||
@@ -123,6 +201,10 @@ export default class ArticleViewStock extends PureComponent {
|
|||||||
? rawUnit
|
? rawUnit
|
||||||
: '';
|
: '';
|
||||||
|
|
||||||
|
const incomingItems = extractIncoming(articleData, isParent);
|
||||||
|
const totalIncoming = incomingItems.reduce((sum, inc) => sum + inc.amount, 0);
|
||||||
|
const hasIncoming = totalIncoming > 0;
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<>
|
<>
|
||||||
<PanelTile
|
<PanelTile
|
||||||
@@ -292,8 +374,8 @@ export default class ArticleViewStock extends PureComponent {
|
|||||||
)}
|
)}
|
||||||
</Box>
|
</Box>
|
||||||
|
|
||||||
{/* Bottom section: Per-warehouse breakdown */}
|
{/* Bottom section: Per-warehouse breakdown & incoming shipments */}
|
||||||
{isTrackStock && hasWarehouses ? (
|
{hasWarehouses || hasIncoming ? (
|
||||||
<Box
|
<Box
|
||||||
sx={{
|
sx={{
|
||||||
mt: 1,
|
mt: 1,
|
||||||
@@ -309,65 +391,176 @@ export default class ArticleViewStock extends PureComponent {
|
|||||||
}}
|
}}
|
||||||
>
|
>
|
||||||
<Box sx={{ display: 'flex', flexDirection: 'column', gap: 0.5 }}>
|
<Box sx={{ display: 'flex', flexDirection: 'column', gap: 0.5 }}>
|
||||||
{warehouses.map((wh) => (
|
{/* Warehouse stocks */}
|
||||||
<Box
|
{hasWarehouses ? (
|
||||||
key={wh.id}
|
<>
|
||||||
sx={{
|
{hasIncoming ? (
|
||||||
display: 'flex',
|
|
||||||
alignItems: 'center',
|
|
||||||
justifyContent: 'space-between',
|
|
||||||
py: 0.35,
|
|
||||||
px: 0.75,
|
|
||||||
borderRadius: 1,
|
|
||||||
backgroundColor: VEIL_PANEL,
|
|
||||||
}}
|
|
||||||
>
|
|
||||||
<Box
|
|
||||||
sx={{
|
|
||||||
display: 'flex',
|
|
||||||
alignItems: 'center',
|
|
||||||
minWidth: 0,
|
|
||||||
mr: 1,
|
|
||||||
}}
|
|
||||||
>
|
|
||||||
<WarehouseIcon
|
|
||||||
sx={{
|
|
||||||
fontSize: 15,
|
|
||||||
color: 'text.secondary',
|
|
||||||
mr: 0.5,
|
|
||||||
flexShrink: 0,
|
|
||||||
}}
|
|
||||||
/>
|
|
||||||
<Typography
|
<Typography
|
||||||
variant="body2"
|
variant="caption"
|
||||||
noWrap
|
|
||||||
title={wh.name}
|
|
||||||
sx={{
|
sx={{
|
||||||
fontWeight: 500,
|
fontSize: '0.68rem',
|
||||||
fontSize: '0.82rem',
|
fontWeight: 700,
|
||||||
color: 'text.primary',
|
color: 'text.secondary',
|
||||||
|
textTransform: 'uppercase',
|
||||||
|
letterSpacing: 0.5,
|
||||||
|
px: 0.5,
|
||||||
|
mb: 0.1,
|
||||||
|
display: 'block',
|
||||||
}}
|
}}
|
||||||
>
|
>
|
||||||
{wh.name}
|
Lagerorte
|
||||||
</Typography>
|
</Typography>
|
||||||
</Box>
|
) : null}
|
||||||
|
{warehouses.map((wh) => (
|
||||||
|
<Box
|
||||||
|
key={wh.id}
|
||||||
|
sx={{
|
||||||
|
display: 'flex',
|
||||||
|
alignItems: 'center',
|
||||||
|
justifyContent: 'space-between',
|
||||||
|
py: 0.35,
|
||||||
|
px: 0.75,
|
||||||
|
borderRadius: 1,
|
||||||
|
backgroundColor: VEIL_PANEL,
|
||||||
|
}}
|
||||||
|
>
|
||||||
|
<Box
|
||||||
|
sx={{
|
||||||
|
display: 'flex',
|
||||||
|
alignItems: 'center',
|
||||||
|
minWidth: 0,
|
||||||
|
mr: 1,
|
||||||
|
}}
|
||||||
|
>
|
||||||
|
<WarehouseIcon
|
||||||
|
sx={{
|
||||||
|
fontSize: 15,
|
||||||
|
color: 'text.secondary',
|
||||||
|
mr: 0.5,
|
||||||
|
flexShrink: 0,
|
||||||
|
}}
|
||||||
|
/>
|
||||||
|
<Typography
|
||||||
|
variant="body2"
|
||||||
|
noWrap
|
||||||
|
title={wh.name}
|
||||||
|
sx={{
|
||||||
|
fontWeight: 500,
|
||||||
|
fontSize: '0.82rem',
|
||||||
|
color: 'text.primary',
|
||||||
|
}}
|
||||||
|
>
|
||||||
|
{wh.name}
|
||||||
|
</Typography>
|
||||||
|
</Box>
|
||||||
|
|
||||||
|
<Typography
|
||||||
|
variant="body2"
|
||||||
|
sx={{
|
||||||
|
fontWeight: 700,
|
||||||
|
fontSize: '0.82rem',
|
||||||
|
flexShrink: 0,
|
||||||
|
color:
|
||||||
|
Number(wh.stock) > 0
|
||||||
|
? 'text.primary'
|
||||||
|
: 'text.secondary',
|
||||||
|
}}
|
||||||
|
>
|
||||||
|
{formatStock(wh.stock)}
|
||||||
|
</Typography>
|
||||||
|
</Box>
|
||||||
|
))}
|
||||||
|
</>
|
||||||
|
) : null}
|
||||||
|
|
||||||
|
{/* Incoming shipments */}
|
||||||
|
{hasIncoming ? (
|
||||||
|
<>
|
||||||
<Typography
|
<Typography
|
||||||
variant="body2"
|
variant="caption"
|
||||||
sx={{
|
sx={{
|
||||||
|
fontSize: '0.68rem',
|
||||||
fontWeight: 700,
|
fontWeight: 700,
|
||||||
fontSize: '0.82rem',
|
color: 'text.secondary',
|
||||||
flexShrink: 0,
|
textTransform: 'uppercase',
|
||||||
color:
|
letterSpacing: 0.5,
|
||||||
Number(wh.stock) > 0
|
px: 0.5,
|
||||||
? 'text.primary'
|
mt: hasWarehouses ? 0.75 : 0,
|
||||||
: 'text.secondary',
|
mb: 0.1,
|
||||||
|
display: 'block',
|
||||||
}}
|
}}
|
||||||
>
|
>
|
||||||
{formatStock(wh.stock)}
|
Im Zulauf
|
||||||
</Typography>
|
</Typography>
|
||||||
</Box>
|
{incomingItems.map((inc, idx) => {
|
||||||
))}
|
const dateLabel = inc.date ? formatDate(inc.date) : null;
|
||||||
|
const label = [
|
||||||
|
inc.supplierName || 'Lieferant',
|
||||||
|
dateLabel,
|
||||||
|
]
|
||||||
|
.filter(Boolean)
|
||||||
|
.join(' – ');
|
||||||
|
|
||||||
|
return (
|
||||||
|
<Box
|
||||||
|
key={idx}
|
||||||
|
title={label}
|
||||||
|
sx={{
|
||||||
|
display: 'flex',
|
||||||
|
alignItems: 'center',
|
||||||
|
justifyContent: 'space-between',
|
||||||
|
py: 0.35,
|
||||||
|
px: 0.75,
|
||||||
|
borderRadius: 1,
|
||||||
|
backgroundColor: VEIL_PANEL,
|
||||||
|
}}
|
||||||
|
>
|
||||||
|
<Box
|
||||||
|
sx={{
|
||||||
|
display: 'flex',
|
||||||
|
alignItems: 'center',
|
||||||
|
minWidth: 0,
|
||||||
|
mr: 1,
|
||||||
|
}}
|
||||||
|
>
|
||||||
|
<LocalShippingOutlinedIcon
|
||||||
|
sx={{
|
||||||
|
fontSize: 15,
|
||||||
|
color: 'text.secondary',
|
||||||
|
mr: 0.6,
|
||||||
|
flexShrink: 0,
|
||||||
|
transform: 'scaleX(-1)',
|
||||||
|
}}
|
||||||
|
/>
|
||||||
|
<Typography
|
||||||
|
variant="body2"
|
||||||
|
noWrap
|
||||||
|
sx={{
|
||||||
|
fontWeight: 500,
|
||||||
|
fontSize: '0.82rem',
|
||||||
|
color: 'text.primary',
|
||||||
|
}}
|
||||||
|
>
|
||||||
|
{label}
|
||||||
|
</Typography>
|
||||||
|
</Box>
|
||||||
|
|
||||||
|
<Typography
|
||||||
|
variant="body2"
|
||||||
|
sx={{
|
||||||
|
fontWeight: 700,
|
||||||
|
fontSize: '0.82rem',
|
||||||
|
flexShrink: 0,
|
||||||
|
color: 'text.primary',
|
||||||
|
}}
|
||||||
|
>
|
||||||
|
+{formatStock(inc.amount)}
|
||||||
|
</Typography>
|
||||||
|
</Box>
|
||||||
|
);
|
||||||
|
})}
|
||||||
|
</>
|
||||||
|
) : null}
|
||||||
</Box>
|
</Box>
|
||||||
</Box>
|
</Box>
|
||||||
) : null}
|
) : null}
|
||||||
|
|||||||
Reference in New Issue
Block a user