u
This commit is contained in:
@@ -45,7 +45,7 @@ import {
|
|||||||
alpha,
|
alpha,
|
||||||
} from '../../../colors';
|
} from '../../../colors';
|
||||||
|
|
||||||
function getVariantDetails(child, allArticles, defaultTaxRate) {
|
function getVariantDetails(child, allArticles, defaultTaxRate, parentArticle) {
|
||||||
const cached = child?.sku ? getArticle(child.sku) : null;
|
const cached = child?.sku ? getArticle(child.sku) : null;
|
||||||
const fromIndex = !cached && child?.sku
|
const fromIndex = !cached && child?.sku
|
||||||
? (allArticles || []).find((a) => a.sku === child.sku)
|
? (allArticles || []).find((a) => a.sku === child.sku)
|
||||||
@@ -56,14 +56,30 @@ function getVariantDetails(child, allArticles, defaultTaxRate) {
|
|||||||
const gross = getArticleGross(merged, defaultTaxRate);
|
const gross = getArticleGross(merged, defaultTaxRate);
|
||||||
const priceDisplay = gross != null && Number.isFinite(gross) ? formatPrice(gross) : null;
|
const priceDisplay = gross != null && Number.isFinite(gross) ? formatPrice(gross) : null;
|
||||||
|
|
||||||
// 2. Stock & Unit
|
// 2. Stock tracking
|
||||||
|
const rawTrack =
|
||||||
|
merged.track_stock ??
|
||||||
|
merged.trackStock ??
|
||||||
|
child?.trackStock ??
|
||||||
|
child?.track_stock ??
|
||||||
|
parentArticle?.track_stock ??
|
||||||
|
parentArticle?.trackStock;
|
||||||
|
|
||||||
|
const trackStock =
|
||||||
|
rawTrack !== undefined
|
||||||
|
? rawTrack !== false && rawTrack !== 0 && rawTrack !== '0'
|
||||||
|
: true;
|
||||||
|
|
||||||
|
// 3. Stock & Unit
|
||||||
let stockVal = null;
|
let stockVal = null;
|
||||||
if (Array.isArray(merged.warehouses) && merged.warehouses.length > 0) {
|
if (trackStock) {
|
||||||
stockVal = merged.warehouses.reduce((sum, wh) => sum + (Number(wh.stock) || 0), 0);
|
if (Array.isArray(merged.warehouses) && merged.warehouses.length > 0) {
|
||||||
} else if (merged.stock != null && !Number.isNaN(Number(merged.stock))) {
|
stockVal = merged.warehouses.reduce((sum, wh) => sum + (Number(wh.stock) || 0), 0);
|
||||||
stockVal = Number(merged.stock);
|
} else if (merged.stock != null && !Number.isNaN(Number(merged.stock))) {
|
||||||
} else if (child?.stock != null && !Number.isNaN(Number(child.stock))) {
|
stockVal = Number(merged.stock);
|
||||||
stockVal = Number(child.stock);
|
} else if (child?.stock != null && !Number.isNaN(Number(child.stock))) {
|
||||||
|
stockVal = Number(child.stock);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
const rawUnit =
|
const rawUnit =
|
||||||
@@ -76,9 +92,9 @@ function getVariantDetails(child, allArticles, defaultTaxRate) {
|
|||||||
rawUnit && !['stk', 'stück', 'pc', 'stk.'].includes(rawUnit.trim().toLowerCase())
|
rawUnit && !['stk', 'stück', 'pc', 'stk.'].includes(rawUnit.trim().toLowerCase())
|
||||||
? ` ${rawUnit}`
|
? ` ${rawUnit}`
|
||||||
: '';
|
: '';
|
||||||
const stockDisplay = stockVal != null ? `${formatStock(stockVal)}${unit}` : null;
|
const stockDisplay = trackStock && stockVal != null ? `${formatStock(stockVal)}${unit}` : null;
|
||||||
|
|
||||||
// 3. EAN(s)
|
// 4. EAN(s)
|
||||||
const eanCandidates = [];
|
const eanCandidates = [];
|
||||||
const rawEans = merged.eans ?? child?.eans;
|
const rawEans = merged.eans ?? child?.eans;
|
||||||
if (Array.isArray(rawEans)) {
|
if (Array.isArray(rawEans)) {
|
||||||
@@ -103,6 +119,7 @@ function getVariantDetails(child, allArticles, defaultTaxRate) {
|
|||||||
stockDisplay,
|
stockDisplay,
|
||||||
primaryEan,
|
primaryEan,
|
||||||
allEans: eanCandidates,
|
allEans: eanCandidates,
|
||||||
|
trackStock,
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -199,7 +216,7 @@ export default class ArticleViewLists extends PureComponent {
|
|||||||
if (!this._cancelled && parent?.children) {
|
if (!this._cancelled && parent?.children) {
|
||||||
this.ensureChildren(parent.children);
|
this.ensureChildren(parent.children);
|
||||||
}
|
}
|
||||||
}).catch(() => {});
|
}).catch(() => { });
|
||||||
}
|
}
|
||||||
|
|
||||||
void this.loadAllArticles();
|
void this.loadAllArticles();
|
||||||
@@ -220,7 +237,7 @@ export default class ArticleViewLists extends PureComponent {
|
|||||||
if (!this._cancelled && parent?.children) {
|
if (!this._cancelled && parent?.children) {
|
||||||
this.ensureChildren(parent.children);
|
this.ensureChildren(parent.children);
|
||||||
}
|
}
|
||||||
}).catch(() => {});
|
}).catch(() => { });
|
||||||
} else {
|
} else {
|
||||||
const parent = getArticle(this.props.article.parentSku);
|
const parent = getArticle(this.props.article.parentSku);
|
||||||
if (parent?.children) {
|
if (parent?.children) {
|
||||||
@@ -268,7 +285,7 @@ export default class ArticleViewLists extends PureComponent {
|
|||||||
if (!Array.isArray(children)) return;
|
if (!Array.isArray(children)) return;
|
||||||
for (const child of children) {
|
for (const child of children) {
|
||||||
if (child?.sku && !getArticle(child.sku)) {
|
if (child?.sku && !getArticle(child.sku)) {
|
||||||
void artikelAutomat.actions.loadArticle(child.sku).catch(() => {});
|
void artikelAutomat.actions.loadArticle(child.sku).catch(() => { });
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -393,30 +410,41 @@ export default class ArticleViewLists extends PureComponent {
|
|||||||
const { selectedChildValueId, newChildText, isCustomChildValue, busy } = this.state;
|
const { selectedChildValueId, newChildText, isCustomChildValue, busy } = this.state;
|
||||||
if (busy || !article?.sku) return;
|
if (busy || !article?.sku) return;
|
||||||
|
|
||||||
|
const val = newChildText.trim();
|
||||||
const payload = {};
|
const payload = {};
|
||||||
if (isCustomChildValue) {
|
|
||||||
const val = newChildText.trim();
|
if (val && (isCustomChildValue || !selectedChildValueId)) {
|
||||||
if (!val) return;
|
payload.value = val;
|
||||||
|
} else if (selectedChildValueId) {
|
||||||
|
payload.attributeValueId = Number(selectedChildValueId);
|
||||||
|
} else if (val) {
|
||||||
payload.value = val;
|
payload.value = val;
|
||||||
} else {
|
} else {
|
||||||
if (!selectedChildValueId) return;
|
return;
|
||||||
payload.attributeValueId = Number(selectedChildValueId);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
this.setState({ busy: true });
|
this.setState({ busy: true });
|
||||||
try {
|
try {
|
||||||
const api = this.getApi();
|
const api = this.getApi();
|
||||||
await api.addChild(article.sku, payload);
|
const res = await api.addChild(article.sku, payload);
|
||||||
if (this._cancelled) return;
|
if (this._cancelled) return;
|
||||||
|
|
||||||
|
if (res?.sku) {
|
||||||
|
void artikelAutomat.actions.loadArticle(res.sku).catch(() => { });
|
||||||
|
}
|
||||||
|
|
||||||
await artikelAutomat.actions.reloadArticle(article.sku);
|
await artikelAutomat.actions.reloadArticle(article.sku);
|
||||||
if (this._cancelled) return;
|
if (this._cancelled) return;
|
||||||
|
|
||||||
|
void articleIndexAutomat.actions.reload().catch(() => { });
|
||||||
|
void companyAutomat.actions.loadAttributes?.().catch?.(() => { });
|
||||||
|
|
||||||
enqueueSnackbar('Variante erfolgreich angelegt.', { variant: 'success' });
|
enqueueSnackbar('Variante erfolgreich angelegt.', { variant: 'success' });
|
||||||
this.setState({
|
this.setState({
|
||||||
busy: false,
|
busy: false,
|
||||||
selectedChildValueId: '',
|
selectedChildValueId: '',
|
||||||
newChildText: '',
|
newChildText: '',
|
||||||
|
isCustomChildValue: false,
|
||||||
});
|
});
|
||||||
} catch (err) {
|
} catch (err) {
|
||||||
if (this._cancelled) return;
|
if (this._cancelled) return;
|
||||||
@@ -491,17 +519,17 @@ export default class ArticleViewLists extends PureComponent {
|
|||||||
const nextItems =
|
const nextItems =
|
||||||
existingIndex >= 0
|
existingIndex >= 0
|
||||||
? currentItems.map((item, idx) =>
|
? currentItems.map((item, idx) =>
|
||||||
idx === existingIndex ? { ...item, count: item.count + count } : item
|
idx === existingIndex ? { ...item, count: item.count + count } : item
|
||||||
)
|
)
|
||||||
: [
|
: [
|
||||||
...currentItems,
|
...currentItems,
|
||||||
{
|
{
|
||||||
articleId: stuecklisteTargetArticle.id,
|
articleId: stuecklisteTargetArticle.id,
|
||||||
sku: stuecklisteTargetArticle.sku,
|
sku: stuecklisteTargetArticle.sku,
|
||||||
count,
|
count,
|
||||||
sort: currentItems.length,
|
sort: currentItems.length,
|
||||||
},
|
},
|
||||||
];
|
];
|
||||||
|
|
||||||
this.setState({ busy: true });
|
this.setState({ busy: true });
|
||||||
try {
|
try {
|
||||||
@@ -615,20 +643,20 @@ export default class ArticleViewLists extends PureComponent {
|
|||||||
const nextOptions =
|
const nextOptions =
|
||||||
existingIndex >= 0
|
existingIndex >= 0
|
||||||
? currentOptions.map((opt, idx) =>
|
? currentOptions.map((opt, idx) =>
|
||||||
idx === existingIndex
|
idx === existingIndex
|
||||||
? { ...opt, count: opt.count + count, mandated: Boolean(optionMandated) }
|
? { ...opt, count: opt.count + count, mandated: Boolean(optionMandated) }
|
||||||
: opt
|
: opt
|
||||||
)
|
)
|
||||||
: [
|
: [
|
||||||
...currentOptions,
|
...currentOptions,
|
||||||
{
|
{
|
||||||
articleId: optionTargetArticle.id,
|
articleId: optionTargetArticle.id,
|
||||||
sku: optionTargetArticle.sku,
|
sku: optionTargetArticle.sku,
|
||||||
count,
|
count,
|
||||||
sort: currentOptions.length,
|
sort: currentOptions.length,
|
||||||
mandated: Boolean(optionMandated),
|
mandated: Boolean(optionMandated),
|
||||||
},
|
},
|
||||||
];
|
];
|
||||||
|
|
||||||
this.setState({ busy: true });
|
this.setState({ busy: true });
|
||||||
try {
|
try {
|
||||||
@@ -834,70 +862,70 @@ export default class ArticleViewLists extends PureComponent {
|
|||||||
}}
|
}}
|
||||||
>
|
>
|
||||||
{stuecklisteItems.map((item) => (
|
{stuecklisteItems.map((item) => (
|
||||||
<Box
|
<Box
|
||||||
key={item.id || item.sku}
|
key={item.id || item.sku}
|
||||||
|
sx={{
|
||||||
|
display: 'flex',
|
||||||
|
alignItems: 'center',
|
||||||
|
justifyContent: 'space-between',
|
||||||
|
px: 1,
|
||||||
|
py: 0.4,
|
||||||
|
borderRadius: 1,
|
||||||
|
bgcolor: 'background.paper',
|
||||||
|
border: '1px solid',
|
||||||
|
borderColor: 'divider',
|
||||||
|
}}
|
||||||
|
>
|
||||||
|
<Box sx={{ minWidth: 0, display: 'flex', alignItems: 'center', gap: 0.75 }}>
|
||||||
|
<Chip
|
||||||
|
label={`${item.count}x`}
|
||||||
|
size="small"
|
||||||
|
sx={{ height: 20, fontSize: '0.72rem', fontWeight: 700, px: 0.25 }}
|
||||||
|
/>
|
||||||
|
<Box sx={{ minWidth: 0, display: 'flex', flexDirection: 'column' }}>
|
||||||
|
<Typography
|
||||||
|
variant="body2"
|
||||||
|
sx={{
|
||||||
|
fontWeight: 600,
|
||||||
|
fontSize: '0.82rem',
|
||||||
|
lineHeight: 1.2,
|
||||||
|
overflow: 'hidden',
|
||||||
|
textOverflow: 'ellipsis',
|
||||||
|
whiteSpace: 'nowrap',
|
||||||
|
}}
|
||||||
|
>
|
||||||
|
{item.name || item.sku}
|
||||||
|
</Typography>
|
||||||
|
<Link
|
||||||
|
component={RouterLink}
|
||||||
|
to={artikelDetailPath(item.sku)}
|
||||||
|
sx={{
|
||||||
|
fontSize: '0.72rem',
|
||||||
|
fontFamily: 'monospace',
|
||||||
|
color: 'text.secondary',
|
||||||
|
textDecoration: 'none',
|
||||||
|
'&:hover': { textDecoration: 'underline' },
|
||||||
|
}}
|
||||||
|
>
|
||||||
|
{item.sku}
|
||||||
|
</Link>
|
||||||
|
</Box>
|
||||||
|
</Box>
|
||||||
|
|
||||||
|
<IconButton
|
||||||
|
size="small"
|
||||||
|
disabled={busy}
|
||||||
|
onClick={() => this.handleRemoveStuecklisteItem(item.sku)}
|
||||||
sx={{
|
sx={{
|
||||||
display: 'flex',
|
p: 0.25,
|
||||||
alignItems: 'center',
|
color: 'text.secondary',
|
||||||
justifyContent: 'space-between',
|
'&:hover': { color: 'error.main' },
|
||||||
px: 1,
|
|
||||||
py: 0.4,
|
|
||||||
borderRadius: 1,
|
|
||||||
bgcolor: 'background.paper',
|
|
||||||
border: '1px solid',
|
|
||||||
borderColor: 'divider',
|
|
||||||
}}
|
}}
|
||||||
>
|
>
|
||||||
<Box sx={{ minWidth: 0, display: 'flex', alignItems: 'center', gap: 0.75 }}>
|
<DeleteOutlinedIcon sx={{ fontSize: 16 }} />
|
||||||
<Chip
|
</IconButton>
|
||||||
label={`${item.count}x`}
|
</Box>
|
||||||
size="small"
|
))
|
||||||
sx={{ height: 20, fontSize: '0.72rem', fontWeight: 700, px: 0.25 }}
|
|
||||||
/>
|
|
||||||
<Box sx={{ minWidth: 0, display: 'flex', flexDirection: 'column' }}>
|
|
||||||
<Typography
|
|
||||||
variant="body2"
|
|
||||||
sx={{
|
|
||||||
fontWeight: 600,
|
|
||||||
fontSize: '0.82rem',
|
|
||||||
lineHeight: 1.2,
|
|
||||||
overflow: 'hidden',
|
|
||||||
textOverflow: 'ellipsis',
|
|
||||||
whiteSpace: 'nowrap',
|
|
||||||
}}
|
|
||||||
>
|
|
||||||
{item.name || item.sku}
|
|
||||||
</Typography>
|
|
||||||
<Link
|
|
||||||
component={RouterLink}
|
|
||||||
to={artikelDetailPath(item.sku)}
|
|
||||||
sx={{
|
|
||||||
fontSize: '0.72rem',
|
|
||||||
fontFamily: 'monospace',
|
|
||||||
color: 'text.secondary',
|
|
||||||
textDecoration: 'none',
|
|
||||||
'&:hover': { textDecoration: 'underline' },
|
|
||||||
}}
|
|
||||||
>
|
|
||||||
{item.sku}
|
|
||||||
</Link>
|
|
||||||
</Box>
|
|
||||||
</Box>
|
|
||||||
|
|
||||||
<IconButton
|
|
||||||
size="small"
|
|
||||||
disabled={busy}
|
|
||||||
onClick={() => this.handleRemoveStuecklisteItem(item.sku)}
|
|
||||||
sx={{
|
|
||||||
p: 0.25,
|
|
||||||
color: 'text.secondary',
|
|
||||||
'&:hover': { color: 'error.main' },
|
|
||||||
}}
|
|
||||||
>
|
|
||||||
<DeleteOutlinedIcon sx={{ fontSize: 16 }} />
|
|
||||||
</IconButton>
|
|
||||||
</Box>
|
|
||||||
))
|
|
||||||
}
|
}
|
||||||
</Box>
|
</Box>
|
||||||
</Box>
|
</Box>
|
||||||
@@ -1044,81 +1072,81 @@ export default class ArticleViewLists extends PureComponent {
|
|||||||
}}
|
}}
|
||||||
>
|
>
|
||||||
{optionsItems.map((opt) => (
|
{optionsItems.map((opt) => (
|
||||||
<Box
|
<Box
|
||||||
key={opt.id || opt.sku}
|
key={opt.id || opt.sku}
|
||||||
sx={{
|
sx={{
|
||||||
display: 'flex',
|
display: 'flex',
|
||||||
alignItems: 'center',
|
alignItems: 'center',
|
||||||
justifyContent: 'space-between',
|
justifyContent: 'space-between',
|
||||||
px: 1,
|
px: 1,
|
||||||
py: 0.4,
|
py: 0.4,
|
||||||
borderRadius: 1,
|
borderRadius: 1,
|
||||||
bgcolor: 'background.paper',
|
bgcolor: 'background.paper',
|
||||||
border: '1px solid',
|
border: '1px solid',
|
||||||
borderColor: 'divider',
|
borderColor: 'divider',
|
||||||
}}
|
}}
|
||||||
>
|
>
|
||||||
<Box sx={{ minWidth: 0, display: 'flex', alignItems: 'center', gap: 0.75 }}>
|
<Box sx={{ minWidth: 0, display: 'flex', alignItems: 'center', gap: 0.75 }}>
|
||||||
<Chip
|
<Chip
|
||||||
label={`${opt.count}x`}
|
label={`${opt.count}x`}
|
||||||
size="small"
|
size="small"
|
||||||
sx={{ height: 20, fontSize: '0.72rem', fontWeight: 700, px: 0.25 }}
|
sx={{ height: 20, fontSize: '0.72rem', fontWeight: 700, px: 0.25 }}
|
||||||
/>
|
/>
|
||||||
<Box sx={{ minWidth: 0, display: 'flex', flexDirection: 'column' }}>
|
<Box sx={{ minWidth: 0, display: 'flex', flexDirection: 'column' }}>
|
||||||
<Typography
|
<Typography
|
||||||
variant="body2"
|
variant="body2"
|
||||||
|
sx={{
|
||||||
|
fontWeight: 600,
|
||||||
|
fontSize: '0.82rem',
|
||||||
|
lineHeight: 1.2,
|
||||||
|
overflow: 'hidden',
|
||||||
|
textOverflow: 'ellipsis',
|
||||||
|
whiteSpace: 'nowrap',
|
||||||
|
}}
|
||||||
|
>
|
||||||
|
{opt.name || opt.sku}
|
||||||
|
</Typography>
|
||||||
|
<Box sx={{ display: 'flex', alignItems: 'center', gap: 0.75 }}>
|
||||||
|
<Link
|
||||||
|
component={RouterLink}
|
||||||
|
to={artikelDetailPath(opt.sku)}
|
||||||
sx={{
|
sx={{
|
||||||
fontWeight: 600,
|
fontSize: '0.72rem',
|
||||||
fontSize: '0.82rem',
|
fontFamily: 'monospace',
|
||||||
lineHeight: 1.2,
|
color: 'text.secondary',
|
||||||
overflow: 'hidden',
|
textDecoration: 'none',
|
||||||
textOverflow: 'ellipsis',
|
'&:hover': { textDecoration: 'underline' },
|
||||||
whiteSpace: 'nowrap',
|
|
||||||
}}
|
}}
|
||||||
>
|
>
|
||||||
{opt.name || opt.sku}
|
{opt.sku}
|
||||||
</Typography>
|
</Link>
|
||||||
<Box sx={{ display: 'flex', alignItems: 'center', gap: 0.75 }}>
|
{opt.mandated ? (
|
||||||
<Link
|
<Chip
|
||||||
component={RouterLink}
|
label="Fest"
|
||||||
to={artikelDetailPath(opt.sku)}
|
size="small"
|
||||||
sx={{
|
color="warning"
|
||||||
fontSize: '0.72rem',
|
variant="outlined"
|
||||||
fontFamily: 'monospace',
|
sx={{ height: 16, fontSize: '0.65rem', fontWeight: 600 }}
|
||||||
color: 'text.secondary',
|
/>
|
||||||
textDecoration: 'none',
|
) : null}
|
||||||
'&:hover': { textDecoration: 'underline' },
|
|
||||||
}}
|
|
||||||
>
|
|
||||||
{opt.sku}
|
|
||||||
</Link>
|
|
||||||
{opt.mandated ? (
|
|
||||||
<Chip
|
|
||||||
label="Fest"
|
|
||||||
size="small"
|
|
||||||
color="warning"
|
|
||||||
variant="outlined"
|
|
||||||
sx={{ height: 16, fontSize: '0.65rem', fontWeight: 600 }}
|
|
||||||
/>
|
|
||||||
) : null}
|
|
||||||
</Box>
|
|
||||||
</Box>
|
</Box>
|
||||||
</Box>
|
</Box>
|
||||||
|
|
||||||
<IconButton
|
|
||||||
size="small"
|
|
||||||
disabled={busy}
|
|
||||||
onClick={() => this.handleRemoveOption(opt.sku)}
|
|
||||||
sx={{
|
|
||||||
p: 0.25,
|
|
||||||
color: 'text.secondary',
|
|
||||||
'&:hover': { color: 'error.main' },
|
|
||||||
}}
|
|
||||||
>
|
|
||||||
<DeleteOutlinedIcon sx={{ fontSize: 16 }} />
|
|
||||||
</IconButton>
|
|
||||||
</Box>
|
</Box>
|
||||||
))
|
|
||||||
|
<IconButton
|
||||||
|
size="small"
|
||||||
|
disabled={busy}
|
||||||
|
onClick={() => this.handleRemoveOption(opt.sku)}
|
||||||
|
sx={{
|
||||||
|
p: 0.25,
|
||||||
|
color: 'text.secondary',
|
||||||
|
'&:hover': { color: 'error.main' },
|
||||||
|
}}
|
||||||
|
>
|
||||||
|
<DeleteOutlinedIcon sx={{ fontSize: 16 }} />
|
||||||
|
</IconButton>
|
||||||
|
</Box>
|
||||||
|
))
|
||||||
}
|
}
|
||||||
</Box>
|
</Box>
|
||||||
</Box>
|
</Box>
|
||||||
@@ -1211,14 +1239,14 @@ export default class ArticleViewLists extends PureComponent {
|
|||||||
const siblings = hasSelf
|
const siblings = hasSelf
|
||||||
? childrenList
|
? childrenList
|
||||||
: [
|
: [
|
||||||
...childrenList,
|
...childrenList,
|
||||||
{
|
{
|
||||||
id: articleData.id,
|
id: articleData.id,
|
||||||
sku: articleData.sku,
|
sku: articleData.sku,
|
||||||
name: articleData.name,
|
name: articleData.name,
|
||||||
attributeValue: variationValue,
|
attributeValue: variationValue,
|
||||||
},
|
},
|
||||||
];
|
];
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<Box sx={{ display: 'flex', flexDirection: 'column', gap: 1, flex: 1, minHeight: 0 }}>
|
<Box sx={{ display: 'flex', flexDirection: 'column', gap: 1, flex: 1, minHeight: 0 }}>
|
||||||
@@ -1348,7 +1376,8 @@ export default class ArticleViewLists extends PureComponent {
|
|||||||
stockDisplay,
|
stockDisplay,
|
||||||
primaryEan,
|
primaryEan,
|
||||||
allEans,
|
allEans,
|
||||||
} = getVariantDetails(sibling, allArticles, defaultTaxRate);
|
trackStock,
|
||||||
|
} = getVariantDetails(sibling, allArticles, defaultTaxRate, parentArticle);
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<Box
|
<Box
|
||||||
@@ -1465,7 +1494,7 @@ export default class ArticleViewLists extends PureComponent {
|
|||||||
sx={{
|
sx={{
|
||||||
fontSize: '0.74rem',
|
fontSize: '0.74rem',
|
||||||
fontWeight: 600,
|
fontWeight: 600,
|
||||||
color: stockVal == null ? 'text.disabled' : stockVal > 0 ? 'success.dark' : 'error.main',
|
color: !trackStock || stockVal == null ? 'text.disabled' : stockVal > 0 ? 'success.dark' : 'error.main',
|
||||||
whiteSpace: 'nowrap',
|
whiteSpace: 'nowrap',
|
||||||
}}
|
}}
|
||||||
>
|
>
|
||||||
@@ -1584,7 +1613,7 @@ export default class ArticleViewLists extends PureComponent {
|
|||||||
sx={{
|
sx={{
|
||||||
fontSize: '0.74rem',
|
fontSize: '0.74rem',
|
||||||
fontWeight: 600,
|
fontWeight: 600,
|
||||||
color: stockVal == null ? 'text.disabled' : stockVal > 0 ? 'success.dark' : 'error.main',
|
color: !trackStock || stockVal == null ? 'text.disabled' : stockVal > 0 ? 'success.dark' : 'error.main',
|
||||||
whiteSpace: 'nowrap',
|
whiteSpace: 'nowrap',
|
||||||
}}
|
}}
|
||||||
>
|
>
|
||||||
@@ -1908,11 +1937,7 @@ export default class ArticleViewLists extends PureComponent {
|
|||||||
<Typography variant="caption" sx={{ fontWeight: 600, color: 'text.secondary' }}>
|
<Typography variant="caption" sx={{ fontWeight: 600, color: 'text.secondary' }}>
|
||||||
Varianten:
|
Varianten:
|
||||||
</Typography>
|
</Typography>
|
||||||
{children.length === 0 ? (
|
{children.length === 0 ? null : (
|
||||||
<Typography variant="body2" color="text.secondary" sx={{ py: 1, fontSize: '0.8rem' }}>
|
|
||||||
Noch keine Varianten angelegt.
|
|
||||||
</Typography>
|
|
||||||
) : (
|
|
||||||
<Box sx={{ display: 'flex', flexDirection: 'column', gap: 0.5 }}>
|
<Box sx={{ display: 'flex', flexDirection: 'column', gap: 0.5 }}>
|
||||||
{children.map((child) => {
|
{children.map((child) => {
|
||||||
const defaultTaxRate = this.state.company?.taxrate ?? companyAutomat.state.current?.taxrate ?? 19;
|
const defaultTaxRate = this.state.company?.taxrate ?? companyAutomat.state.current?.taxrate ?? 19;
|
||||||
@@ -1922,7 +1947,8 @@ export default class ArticleViewLists extends PureComponent {
|
|||||||
stockDisplay,
|
stockDisplay,
|
||||||
primaryEan,
|
primaryEan,
|
||||||
allEans,
|
allEans,
|
||||||
} = getVariantDetails(child, allArticles, defaultTaxRate);
|
trackStock,
|
||||||
|
} = getVariantDetails(child, allArticles, defaultTaxRate, articleData);
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<Box
|
<Box
|
||||||
@@ -2064,7 +2090,7 @@ export default class ArticleViewLists extends PureComponent {
|
|||||||
sx={{
|
sx={{
|
||||||
fontSize: '0.74rem',
|
fontSize: '0.74rem',
|
||||||
fontWeight: 600,
|
fontWeight: 600,
|
||||||
color: stockVal == null ? 'text.disabled' : stockVal > 0 ? 'success.dark' : 'error.main',
|
color: !trackStock || stockVal == null ? 'text.disabled' : stockVal > 0 ? 'success.dark' : 'error.main',
|
||||||
whiteSpace: 'nowrap',
|
whiteSpace: 'nowrap',
|
||||||
}}
|
}}
|
||||||
>
|
>
|
||||||
@@ -2077,7 +2103,6 @@ export default class ArticleViewLists extends PureComponent {
|
|||||||
size="small"
|
size="small"
|
||||||
disabled={busy}
|
disabled={busy}
|
||||||
onClick={() => this.handleOpenRemoveDialog(child)}
|
onClick={() => this.handleOpenRemoveDialog(child)}
|
||||||
title="Variante entfernen"
|
|
||||||
sx={{
|
sx={{
|
||||||
p: 0.35,
|
p: 0.35,
|
||||||
color: 'text.secondary',
|
color: 'text.secondary',
|
||||||
@@ -2098,7 +2123,6 @@ export default class ArticleViewLists extends PureComponent {
|
|||||||
{isCustomChildValue || availableParentValues.length === 0 ? (
|
{isCustomChildValue || availableParentValues.length === 0 ? (
|
||||||
<TextInput
|
<TextInput
|
||||||
label="Neuer Wert"
|
label="Neuer Wert"
|
||||||
placeholder="Neuer Wert..."
|
|
||||||
value={newChildText}
|
value={newChildText}
|
||||||
disabled={busy}
|
disabled={busy}
|
||||||
onChange={(e) => this.setState({ newChildText: e.target.value })}
|
onChange={(e) => this.setState({ newChildText: e.target.value })}
|
||||||
@@ -2143,34 +2167,31 @@ export default class ArticleViewLists extends PureComponent {
|
|||||||
</TextInput>
|
</TextInput>
|
||||||
)}
|
)}
|
||||||
|
|
||||||
<Tooltip title="Variante hinzufügen">
|
<IconButton
|
||||||
<span>
|
size="small"
|
||||||
<IconButton
|
color="primary"
|
||||||
size="small"
|
aria-label="Variante hinzufügen"
|
||||||
color="primary"
|
disabled={
|
||||||
disabled={
|
busy ||
|
||||||
busy ||
|
(isCustomChildValue || availableParentValues.length === 0
|
||||||
(isCustomChildValue || availableParentValues.length === 0
|
? !newChildText.trim()
|
||||||
? !newChildText.trim()
|
: !selectedChildValueId)
|
||||||
: !selectedChildValueId)
|
}
|
||||||
}
|
onClick={this.handleAddChild}
|
||||||
onClick={this.handleAddChild}
|
sx={{
|
||||||
sx={{
|
bgcolor: 'primary.main',
|
||||||
bgcolor: 'primary.main',
|
color: 'primary.contrastText',
|
||||||
color: 'primary.contrastText',
|
'&:hover': { bgcolor: 'primary.dark' },
|
||||||
'&:hover': { bgcolor: 'primary.dark' },
|
'&.Mui-disabled': {
|
||||||
'&.Mui-disabled': {
|
bgcolor: 'action.disabledBackground',
|
||||||
bgcolor: 'action.disabledBackground',
|
color: 'action.disabled',
|
||||||
color: 'action.disabled',
|
},
|
||||||
},
|
p: 0.6,
|
||||||
p: 0.6,
|
flexShrink: 0,
|
||||||
flexShrink: 0,
|
}}
|
||||||
}}
|
>
|
||||||
>
|
{busy ? <CircularProgress size={16} color="inherit" /> : <AddIcon fontSize="small" />}
|
||||||
{busy ? <CircularProgress size={16} color="inherit" /> : <AddIcon fontSize="small" />}
|
</IconButton>
|
||||||
</IconButton>
|
|
||||||
</span>
|
|
||||||
</Tooltip>
|
|
||||||
</Box>
|
</Box>
|
||||||
|
|
||||||
{/* Toggle custom value / predefined value if values exist */}
|
{/* Toggle custom value / predefined value if values exist */}
|
||||||
@@ -2205,16 +2226,16 @@ export default class ArticleViewLists extends PureComponent {
|
|||||||
)}
|
)}
|
||||||
<Box sx={{ mt: 0.5, pt: 1, borderTop: '1px solid', borderColor: 'divider' }}>
|
<Box sx={{ mt: 0.5, pt: 1, borderTop: '1px solid', borderColor: 'divider' }}>
|
||||||
{isStueckliste ||
|
{isStueckliste ||
|
||||||
hasOptions ||
|
hasOptions ||
|
||||||
activeCreatorMode === 'stueckliste' ||
|
activeCreatorMode === 'stueckliste' ||
|
||||||
activeCreatorMode === 'options'
|
activeCreatorMode === 'options'
|
||||||
? this.renderCompoundManager(
|
? this.renderCompoundManager(
|
||||||
isStueckliste,
|
isStueckliste,
|
||||||
hasOptions,
|
hasOptions,
|
||||||
stuecklisteItems,
|
stuecklisteItems,
|
||||||
optionsItems,
|
optionsItems,
|
||||||
selectableOtherArticles
|
selectableOtherArticles
|
||||||
)
|
)
|
||||||
: this.renderStandardView(selectableAttributes, assignedAttributeIds)}
|
: this.renderStandardView(selectableAttributes, assignedAttributeIds)}
|
||||||
</Box>
|
</Box>
|
||||||
</Box>
|
</Box>
|
||||||
@@ -2293,11 +2314,11 @@ export default class ArticleViewLists extends PureComponent {
|
|||||||
<DialogContentText sx={{ fontSize: '0.88rem' }}>
|
<DialogContentText sx={{ fontSize: '0.88rem' }}>
|
||||||
{confirmClearType === 'stueckliste'
|
{confirmClearType === 'stueckliste'
|
||||||
? (hasOptions
|
? (hasOptions
|
||||||
? 'Möchten Sie alle Komponenten aus dieser Stückliste entfernen? Die Optionen bleiben dabei erhalten.'
|
? 'Möchten Sie alle Komponenten aus dieser Stückliste entfernen? Die Optionen bleiben dabei erhalten.'
|
||||||
: 'Möchten Sie alle Komponenten aus dieser Stückliste entfernen und den Artikel wieder als Standard-Artikel führen?')
|
: 'Möchten Sie alle Komponenten aus dieser Stückliste entfernen und den Artikel wieder als Standard-Artikel führen?')
|
||||||
: (isStueckliste
|
: (isStueckliste
|
||||||
? 'Möchten Sie alle Optionen von diesem Artikel entfernen? Die Stückliste bleibt dabei erhalten.'
|
? 'Möchten Sie alle Optionen von diesem Artikel entfernen? Die Stückliste bleibt dabei erhalten.'
|
||||||
: 'Möchten Sie alle Optionen von diesem Artikel entfernen und ihn wieder als Standard-Artikel führen?')}
|
: 'Möchten Sie alle Optionen von diesem Artikel entfernen und ihn wieder als Standard-Artikel führen?')}
|
||||||
</DialogContentText>
|
</DialogContentText>
|
||||||
</DialogContent>
|
</DialogContent>
|
||||||
<DialogActions sx={{ px: 2, pb: 2 }}>
|
<DialogActions sx={{ px: 2, pb: 2 }}>
|
||||||
|
|||||||
Reference in New Issue
Block a user