- Drop `expected_discount_pct`, add `price_uplift DECIMAL(8,4) DEFAULT 1.3` to `qt_competitors` (migration 040); formula: effective_price = price / uplift - Extend `LoadLotMetrics` to return per-PN qty map (`pnQtysByLot`) - Add virtual fields `CompetitorNames`, `PriceSpreadPct`, `PartnumberQtys` to `PricelistItem`; populate via `enrichWarehouseItems` / `enrichCompetitorItems` - Competitor quotes filtered to qty > 0 before lot resolution - New "stock layout" on pricelist detail page for warehouse/competitor: Partnumbers column (PN + qty, only qty>0), Поставщик column, no Настройки/Доступно - Spread badge ±N% shown next to price for competitor rows - Bible updated: pricelist.md, history.md Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
109 lines
5.6 KiB
HTML
109 lines
5.6 KiB
HTML
{{define "title"}}Прайслист - PriceForge{{end}}
|
|
|
|
{{define "content"}}
|
|
<div class="space-y-6">
|
|
<div class="flex items-center justify-between">
|
|
<div class="flex items-center space-x-4">
|
|
<a href="/pricelists" class="text-gray-500 hover:text-gray-700">
|
|
<svg class="w-5 h-5" fill="none" stroke="currentColor" viewBox="0 0 24 24">
|
|
<path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M15 19l-7-7 7-7"></path>
|
|
</svg>
|
|
</a>
|
|
<h1 id="page-title" class="text-2xl font-bold text-gray-900">Загрузка...</h1>
|
|
</div>
|
|
<div class="flex items-center gap-2">
|
|
<button onclick="openPriceChangesReport()" class="px-4 py-2 border border-gray-300 text-gray-700 rounded-md hover:bg-gray-50">
|
|
Отчет по изменениям
|
|
</button>
|
|
<button onclick="exportToCSV()" class="px-4 py-2 bg-orange-600 text-white rounded-md hover:bg-orange-700 flex items-center space-x-2">
|
|
<svg class="w-4 h-4" fill="none" stroke="currentColor" viewBox="0 0 24 24">
|
|
<path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M12 10v6m0 0l-3-3m3 3l3-3m2 8H7a2 2 0 01-2-2V5a2 2 0 012-2h5.586a1 1 0 01.707.293l5.414 5.414a1 1 0 01.293.707V19a2 2 0 01-2 2z"></path>
|
|
</svg>
|
|
<span>Экспорт в CSV</span>
|
|
</button>
|
|
</div>
|
|
</div>
|
|
|
|
<div id="pricelist-info" class="bg-white rounded-lg shadow p-6">
|
|
<div id="pl-notification" class="hidden mb-4 p-3 bg-yellow-50 border border-yellow-200 rounded-lg text-yellow-800"></div>
|
|
<div class="grid grid-cols-2 md:grid-cols-4 gap-4">
|
|
<div>
|
|
<p class="text-sm text-gray-500">Версия</p>
|
|
<p id="pl-version" class="font-mono">-</p>
|
|
</div>
|
|
<div>
|
|
<p class="text-sm text-gray-500">Дата создания</p>
|
|
<p id="pl-date">-</p>
|
|
</div>
|
|
<div>
|
|
<p class="text-sm text-gray-500">Автор</p>
|
|
<p id="pl-author">-</p>
|
|
</div>
|
|
<div>
|
|
<p class="text-sm text-gray-500">Позиций</p>
|
|
<p id="pl-items">-</p>
|
|
</div>
|
|
<div>
|
|
<p class="text-sm text-gray-500">Использований</p>
|
|
<p id="pl-usage">-</p>
|
|
</div>
|
|
<div>
|
|
<p class="text-sm text-gray-500">Статус</p>
|
|
<p id="pl-status">-</p>
|
|
</div>
|
|
<div>
|
|
<p class="text-sm text-gray-500">Истекает</p>
|
|
<p id="pl-expires">-</p>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
|
|
<div class="bg-white rounded-lg shadow overflow-hidden">
|
|
<div class="p-4 border-b">
|
|
<input type="text" id="search-input" placeholder="Поиск по артикулу..."
|
|
class="w-full md:w-64 px-3 py-2 border border-gray-300 rounded-md focus:outline-none focus:ring-2 focus:ring-orange-500">
|
|
</div>
|
|
|
|
<table class="min-w-full divide-y divide-gray-200">
|
|
<thead class="bg-gray-50">
|
|
<tr>
|
|
<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 id="th-competitors" class="hidden px-6 py-3 text-left text-xs font-medium text-gray-500 uppercase">Поставщик</th>
|
|
<th class="px-6 py-3 text-right text-xs font-medium text-gray-500 uppercase">Цена, $</th>
|
|
<th id="th-settings" 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="7" class="px-6 py-4 text-center text-gray-500">Загрузка...</td>
|
|
</tr>
|
|
</tbody>
|
|
</table>
|
|
|
|
<div id="items-pagination" class="p-4 border-t flex justify-between items-center">
|
|
<span id="items-info" class="text-sm text-gray-500"></span>
|
|
<div id="items-pages" class="space-x-2"></div>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
|
|
<div id="price-changes-modal" class="fixed inset-0 bg-black bg-opacity-50 hidden items-center justify-center z-50">
|
|
<div class="bg-white rounded-lg p-6 max-w-4xl w-full mx-4 max-h-[85vh] overflow-hidden flex flex-col">
|
|
<div class="flex items-center justify-between mb-4">
|
|
<h2 class="text-xl font-bold">Отчет по изменениям цен</h2>
|
|
<button type="button" onclick="closePriceChangesModal()" class="text-gray-500 hover:text-gray-700">Закрыть</button>
|
|
</div>
|
|
<div id="price-changes-summary" class="text-sm text-gray-600 mb-4"></div>
|
|
<div id="price-changes-content" class="overflow-auto space-y-4"></div>
|
|
</div>
|
|
</div>
|
|
|
|
<script src="/static/js/pricelist_detail.js"></script>
|
|
{{end}}
|
|
|
|
{{template "base" .}}
|