feat: Add product article number, barcode, and calculated gross price display with updated data fetching and tax zone configuration.

This commit is contained in:
sebseb7
2025-11-24 15:34:19 +01:00
parent d251daa075
commit da9783e7b3
4 changed files with 117 additions and 8 deletions

View File

@@ -136,13 +136,33 @@
}
.product-item {
padding: 0.25rem 0;
padding: 0.5rem 0;
border-bottom: 1px solid #eee;
display: flex;
align-items: center;
gap: 0.75rem;
}
.product-details {
flex: 1;
display: flex;
flex-direction: column;
gap: 0.1rem;
}
.product-meta {
font-size: 0.8rem;
color: #888;
display: flex;
gap: 0.5rem;
}
.product-price {
font-weight: bold;
color: #2d3748;
font-size: 0.95rem;
}
.product-image {
width: 32px;
height: 32px;
@@ -771,6 +791,49 @@
});
}
function renderProducts(products) {
if (!products) return '<div class="loading">Loading products...</div>';
if (products.length === 0) return '<div class="category-products">No products found.</div>';
const items = products.map(p => {
const image = p.images && p.images.length > 0
? `<img src="/api/images/${p.images[0]}/thumbnail" class="product-image" loading="lazy">`
: '<div class="product-image"></div>';
// Calculate Gross Price
let priceDisplay = '';
if (p.fVKNetto !== undefined && p.fVKNetto !== null) {
const net = parseFloat(p.fVKNetto);
const rate = p.fSteuersatz ? parseFloat(p.fSteuersatz) : 19.0; // Default to 19% if missing
const gross = net * (1 + rate / 100);
priceDisplay = `<div class="product-price">${gross.toFixed(2)} €</div>`;
console.log('Product:', p.cName, 'Net:', net, 'Rate:', rate, 'Gross:', gross.toFixed(2));
} else {
console.log('Product missing price:', p.cName, 'fVKNetto:', p.fVKNetto);
}
// Meta info
const metaParts = [];
if (p.cArtNr) metaParts.push(`Art: ${p.cArtNr}`);
if (p.cBarcode) metaParts.push(`EAN: ${p.cBarcode}`);
const metaHtml = metaParts.length > 0 ? `<div class="product-meta">${metaParts.join(' • ')}</div>` : '';
return `
<div class="product-item">
${image}
<div class="product-details">
<div>
<a class="product-name-link" onclick="showProductDetails(${p.kArtikel}, '${p.cName.replace(/'/g, "\\'")}')">${p.cName}</a>
</div>
${metaHtml}
</div>
${priceDisplay}
</div>
`;
}).join('');
return `<div class="category-products">${items}</div>`;
}
function updateCategoryProducts(id) {
const findAndReload = (nodes) => {
for (const node of nodes) {
@@ -971,6 +1034,7 @@
const li = document.createElement('li');
li.className = 'product-item';
// Image
if (p.images && p.images.length > 0) {
const img = document.createElement('img');
img.className = 'product-image';
@@ -981,14 +1045,46 @@
li.appendChild(img);
}
const span = document.createElement('span');
span.className = 'product-name-link';
span.textContent = p.cName;
span.onclick = (e) => {
// Product details container
const detailsDiv = document.createElement('div');
detailsDiv.className = 'product-details';
// Product name
const nameDiv = document.createElement('div');
const nameLink = document.createElement('span');
nameLink.className = 'product-name-link';
nameLink.textContent = p.cName;
nameLink.onclick = (e) => {
e.stopPropagation();
showProductDetails(p.kArtikel);
showProductDetails(p.kArtikel, p.cName);
};
li.appendChild(span);
nameDiv.appendChild(nameLink);
detailsDiv.appendChild(nameDiv);
// Meta info (Article number and barcode)
const metaParts = [];
if (p.cArtNr) metaParts.push(`Art: ${p.cArtNr}`);
if (p.cBarcode) metaParts.push(`EAN: ${p.cBarcode}`);
if (metaParts.length > 0) {
const metaDiv = document.createElement('div');
metaDiv.className = 'product-meta';
metaDiv.textContent = metaParts.join(' • ');
detailsDiv.appendChild(metaDiv);
}
li.appendChild(detailsDiv);
// Price
if (p.fVKNetto !== undefined && p.fVKNetto !== null) {
const net = parseFloat(p.fVKNetto);
const rate = p.fSteuersatz ? parseFloat(p.fSteuersatz) : 19.0;
const gross = net * (1 + rate / 100);
const priceDiv = document.createElement('div');
priceDiv.className = 'product-price';
priceDiv.textContent = `${gross.toFixed(2)}`;
li.appendChild(priceDiv);
}
ul.appendChild(li);
});