Add stock pricelist admin flow with mapping placeholders and warehouse details
This commit is contained in:
@@ -57,13 +57,15 @@
|
||||
<th class="px-6 py-3 text-left text-xs font-medium text-gray-500 uppercase">Артикул</th>
|
||||
<th class="px-6 py-3 text-left text-xs font-medium text-gray-500 uppercase">Категория</th>
|
||||
<th class="px-6 py-3 text-left text-xs font-medium text-gray-500 uppercase">Описание</th>
|
||||
<th id="th-qty" class="hidden px-6 py-3 text-right text-xs font-medium text-gray-500 uppercase">Доступно</th>
|
||||
<th id="th-partnumbers" class="hidden px-6 py-3 text-left text-xs font-medium text-gray-500 uppercase">Partnumbers</th>
|
||||
<th class="px-6 py-3 text-right text-xs font-medium text-gray-500 uppercase">Цена, $</th>
|
||||
<th class="px-6 py-3 text-left text-xs font-medium text-gray-500 uppercase">Настройки</th>
|
||||
</tr>
|
||||
</thead>
|
||||
<tbody id="items-body" class="bg-white divide-y divide-gray-200">
|
||||
<tr>
|
||||
<td colspan="5" class="px-6 py-4 text-center text-gray-500">Загрузка...</td>
|
||||
<td colspan="7" class="px-6 py-4 text-center text-gray-500">Загрузка...</td>
|
||||
</tr>
|
||||
</tbody>
|
||||
</table>
|
||||
@@ -80,6 +82,7 @@
|
||||
let currentPage = 1;
|
||||
let searchQuery = '';
|
||||
let searchTimeout = null;
|
||||
let currentSource = '';
|
||||
|
||||
async function loadPricelistInfo() {
|
||||
try {
|
||||
@@ -87,6 +90,8 @@
|
||||
if (!resp.ok) throw new Error('Pricelist not found');
|
||||
|
||||
const pl = await resp.json();
|
||||
currentSource = pl.source || '';
|
||||
toggleWarehouseColumns();
|
||||
|
||||
document.getElementById('page-title').textContent = `Прайслист ${pl.version}`;
|
||||
document.getElementById('pl-version').textContent = pl.version;
|
||||
@@ -128,13 +133,15 @@
|
||||
|
||||
const resp = await fetch(url);
|
||||
const data = await resp.json();
|
||||
currentSource = data.source || currentSource;
|
||||
toggleWarehouseColumns();
|
||||
|
||||
renderItems(data.items || []);
|
||||
renderItemsPagination(data.total, data.page, data.per_page);
|
||||
} catch (e) {
|
||||
document.getElementById('items-body').innerHTML = `
|
||||
<tr>
|
||||
<td colspan="5" class="px-6 py-4 text-center text-red-500">
|
||||
<td colspan="${itemsColspan()}" class="px-6 py-4 text-center text-red-500">
|
||||
Ошибка загрузки: ${e.message}
|
||||
</td>
|
||||
</tr>
|
||||
@@ -142,6 +149,26 @@
|
||||
}
|
||||
}
|
||||
|
||||
function isWarehouseSource() {
|
||||
return (currentSource || '').toLowerCase() === 'warehouse';
|
||||
}
|
||||
|
||||
function itemsColspan() {
|
||||
return isWarehouseSource() ? 7 : 5;
|
||||
}
|
||||
|
||||
function toggleWarehouseColumns() {
|
||||
const visible = isWarehouseSource();
|
||||
document.getElementById('th-qty').classList.toggle('hidden', !visible);
|
||||
document.getElementById('th-partnumbers').classList.toggle('hidden', !visible);
|
||||
}
|
||||
|
||||
function formatQty(qty) {
|
||||
if (typeof qty !== 'number') return '—';
|
||||
if (Number.isInteger(qty)) return qty.toString();
|
||||
return qty.toLocaleString('ru-RU', { minimumFractionDigits: 0, maximumFractionDigits: 3 });
|
||||
}
|
||||
|
||||
function formatPriceSettings(item) {
|
||||
// Format price settings to match admin pricing interface style
|
||||
let settings = [];
|
||||
@@ -188,7 +215,7 @@
|
||||
if (items.length === 0) {
|
||||
document.getElementById('items-body').innerHTML = `
|
||||
<tr>
|
||||
<td colspan="5" class="px-6 py-4 text-center text-gray-500">
|
||||
<td colspan="${itemsColspan()}" class="px-6 py-4 text-center text-gray-500">
|
||||
${searchQuery ? 'Ничего не найдено' : 'Позиции не найдены'}
|
||||
</td>
|
||||
</tr>
|
||||
@@ -196,10 +223,13 @@
|
||||
return;
|
||||
}
|
||||
|
||||
const showWarehouse = isWarehouseSource();
|
||||
const html = items.map(item => {
|
||||
const price = item.price.toLocaleString('en-US', { minimumFractionDigits: 2, maximumFractionDigits: 2 });
|
||||
const description = item.lot_description || '-';
|
||||
const truncatedDesc = description.length > 60 ? description.substring(0, 60) + '...' : description;
|
||||
const qty = formatQty(item.available_qty);
|
||||
const partnumbers = Array.isArray(item.partnumbers) && item.partnumbers.length > 0 ? item.partnumbers.join(', ') : '—';
|
||||
|
||||
return `
|
||||
<tr class="hover:bg-gray-50">
|
||||
@@ -210,6 +240,8 @@
|
||||
<span class="px-2 py-1 text-xs bg-gray-100 rounded">${item.category || '-'}</span>
|
||||
</td>
|
||||
<td class="px-6 py-3 text-sm text-gray-500" title="${description}">${truncatedDesc}</td>
|
||||
${showWarehouse ? `<td class="px-6 py-3 whitespace-nowrap text-right font-mono">${qty}</td>` : ''}
|
||||
${showWarehouse ? `<td class="px-6 py-3 text-sm text-gray-600" title="${escapeHtml(partnumbers)}">${escapeHtml(partnumbers)}</td>` : ''}
|
||||
<td class="px-6 py-3 whitespace-nowrap text-right font-mono">${price}</td>
|
||||
<td class="px-6 py-3 whitespace-nowrap text-sm"><span class="text-xs bg-gray-100 px-2 py-1 rounded">${formatPriceSettings(item)}</span></td>
|
||||
</tr>
|
||||
|
||||
Reference in New Issue
Block a user