feat: складские цены и «только наличие» — настройки уровня проекта

Добавлен чекбокс «Складские цены» (по аналогии с «Аренда»), управляющий
показом складских цен во всех ценовых интерфейсах конфигурации, включая
CSV-экспорт. «Только наличие» перенесён из настроек цен конфигурации в
настройки проекта и активен только при включённых складских ценах.

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
This commit is contained in:
Mikhail Chusavitin
2026-08-12 17:05:39 +03:00
co-authored by Claude Sonnet 5
parent 18282452a1
commit 9629521495
18 changed files with 244 additions and 166 deletions
+37 -1
View File
@@ -321,6 +321,20 @@
</label>
<div class="text-xs text-gray-500 mt-1">Добавляет вкладку «Аренда» (расчёт стоимости платного тестирования/аренды) на конфигурациях этого проекта.</div>
</div>
<div>
<label class="flex items-center space-x-2">
<input type="checkbox" id="project-settings-show-stock-prices" class="rounded border-gray-300" onchange="applyStockSettingsGating()">
<span class="text-sm font-medium text-gray-700">Складские цены</span>
</label>
<div class="text-xs text-gray-500 mt-1">Показывает складские (Stock) цены во всех ценовых интерфейсах конфигураций этого проекта, включая экспорты CSV.</div>
</div>
<div id="project-settings-only-in-stock-wrap">
<label class="flex items-center space-x-2">
<input type="checkbox" id="project-settings-only-in-stock" class="rounded border-gray-300">
<span class="text-sm font-medium text-gray-700">Только наличие</span>
</label>
<div class="text-xs text-gray-500 mt-1">При добавлении компонентов предлагает только позиции, доступные на складе. Активно только вместе со «Складские цены».</div>
</div>
</div>
<div class="flex justify-end space-x-3 mt-6">
<button onclick="closeProjectSettingsModal()" class="px-4 py-2 text-gray-600 hover:text-gray-800">Отмена</button>
@@ -1261,10 +1275,24 @@ function openProjectSettingsModal() {
document.getElementById('project-settings-name').value = project.name || '';
document.getElementById('project-settings-tracker-url').value = (project.tracker_url || '').trim();
document.getElementById('project-settings-rental-enabled').checked = !!project.rental_enabled;
document.getElementById('project-settings-show-stock-prices').checked = !!project.show_stock_prices;
document.getElementById('project-settings-only-in-stock').checked = !!project.only_in_stock;
applyStockSettingsGating();
document.getElementById('project-settings-modal').classList.remove('hidden');
document.getElementById('project-settings-modal').classList.add('flex');
}
function applyStockSettingsGating() {
const showStockPrices = document.getElementById('project-settings-show-stock-prices').checked;
const onlyInStock = document.getElementById('project-settings-only-in-stock');
const wrap = document.getElementById('project-settings-only-in-stock-wrap');
onlyInStock.disabled = !showStockPrices;
if (!showStockPrices) {
onlyInStock.checked = false;
}
wrap.classList.toggle('opacity-50', !showStockPrices);
}
function closeProjectSettingsModal() {
document.getElementById('project-settings-modal').classList.add('hidden');
document.getElementById('project-settings-modal').classList.remove('flex');
@@ -1277,6 +1305,8 @@ async function saveProjectSettings() {
const name = document.getElementById('project-settings-name').value.trim();
const trackerURL = document.getElementById('project-settings-tracker-url').value.trim();
const rentalEnabled = document.getElementById('project-settings-rental-enabled').checked;
const showStockPrices = document.getElementById('project-settings-show-stock-prices').checked;
const onlyInStock = document.getElementById('project-settings-only-in-stock').checked;
if (!code) {
alert('Введите код проекта');
return;
@@ -1284,7 +1314,7 @@ async function saveProjectSettings() {
const resp = await fetch('/api/projects/' + projectUUID, {
method: 'PUT',
headers: {'Content-Type': 'application/json'},
body: JSON.stringify({code: code, variant: variant, name: name, tracker_url: trackerURL, rental_enabled: rentalEnabled})
body: JSON.stringify({code: code, variant: variant, name: name, tracker_url: trackerURL, rental_enabled: rentalEnabled, show_stock_prices: showStockPrices, only_in_stock: onlyInStock})
});
if (!resp.ok) {
if (resp.status === 409) {
@@ -1521,6 +1551,12 @@ function openExportModal() {
const modal = document.getElementById('project-export-modal');
if (!modal) return;
setProjectExportStatus('', '');
const stockCheckbox = document.getElementById('export-col-stock');
const showStockPrices = !!(project && project.show_stock_prices);
stockCheckbox.disabled = !showStockPrices;
if (!showStockPrices) {
stockCheckbox.checked = false;
}
modal.classList.remove('hidden');
modal.classList.add('flex');
}