(()=>{ 'use strict'; if(window.CateriumTrialDemo)return; const KEY='sunTrialDemoV1',BATCH='trial-demo-v1'; const $=id=>document.getElementById(id); const esc=x=>String(x??'').replace(/[&<>"']/g,c=>({'&':'&','<':'<','>':'>','"':'"',"'":'''}[c])); const money=x=>new Intl.NumberFormat('ru-RU',{maximumFractionDigits:2}).format(Number(x)||0)+' ₽'; const num=x=>new Intl.NumberFormat('ru-RU',{maximumFractionDigits:3}).format(Number(x)||0); const read=(key,fallback)=>{try{return JSON.parse(localStorage.getItem(key))??fallback}catch(_){return fallback}}; const cloud=()=>window.SunCloudV2; const data=()=>window.CateriumDataV1773; const catalog=()=>data()?.catalog.list()||read('sunBoxes',[]); const installed=()=>read(KEY,{})?.version===1; const signedIn=()=>Boolean(cloud()?.getSession?.()?.user&&cloud()?.getWorkspace?.()?.id); const writable=()=>signedIn()&&!cloud()?.isSupportMode?.()&&cloud()?.hasPermission?.('orders.create')&&window.SunSaaSV16?.isWritable?.()!==false; let status=null,statusWorkspace='',pending=null,epoch=0,busy=false; function navigate(id){const label={stock:'Склад',shopping:'Закупки'}[id];const nav=[...document.querySelectorAll('header nav button')].find(b=>String(b.dataset.navLabel||b.textContent||'').trim()===label);if(nav)nav.click();else window.show?.(id);} function message(text){const el=$('ctDemoMessage');if(el)el.textContent=text;} async function refreshStatus(){status=null;statusWorkspace='';render();} function openTrainingSettings(){ const nav=[...document.querySelectorAll('header nav button')].find(b=>String(b.dataset.navLabel||b.textContent||'').trim()==='Настройки'); if(nav)nav.click();else window.show?.('enterprise-settings'); setTimeout(()=>{ const card=$('ctTrainingSettings');if(!card)return; const tab=card.dataset.settingsTab;if(tab)document.querySelector(`[data-settings-tab-target="${tab}"]`)?.click(); setTimeout(()=>{card.scrollIntoView({block:'start',behavior:'smooth'});card.querySelector('input')?.focus({preventScroll:true});},120); },150); } function ensureNotice(host){ let notice=$('ctTrainingNotice'); if(!notice){ notice=document.createElement('div');notice.id='ctTrainingNotice';notice.className='ct-training-notice';notice.setAttribute('role','status'); notice.innerHTML='Включён учебный режим ·'; notice.querySelector('button').addEventListener('click',openTrainingSettings); } if(host.firstElementChild!==notice)host.prepend(notice); } function render(){ const host=$('new');if(!host)return; const clear=()=>{$('ctTrialDemo')?.remove();$('ctTrainingNotice')?.remove();}; if(window.CateriumTrainingCatalog&&!window.CateriumTrainingCatalog.enabled()){clear();return;} const demoItems=catalog().filter(b=>b.demo),items=demoItems.filter(b=>b.ttk),active=installed()&&demoItems.length>0; if(!signedIn()||cloud()?.isSupportMode?.()||(!active&&!status?.canInstall)){clear();return;} // While training is on, the order screen only carries a one-line notice; the guide lives in Settings. if(active)ensureNotice(host);else $('ctTrainingNotice')?.remove(); const target=active?$('ctTrainingSettings'):host; let card=$('ctTrialDemo');if(card&&card.parentElement!==target){card.remove();card=null;} if(!target)return; if(!card){card=document.createElement('section');card.id='ctTrialDemo';card.className=active?'ct-demo-guide':'card';if(active)target.append(card);else target.prepend(card);} const signature=JSON.stringify({active,items:demoItems.map(x=>[x.id,x.name]),upgrade:status?.canUpgrade,can:writable()}); if(card.dataset.signature===signature)return;card.dataset.signature=signature; const previousGuide={open:card.querySelector('details')?.open,selected:$('ctDemoBox')?.value,message:$('ctDemoMessage')?.textContent}; card.innerHTML=active?`
Пробный заказ, склад и закупки

${demoItems.length} тестовых позиций · готовые составы, учебные цены и поставщики

Создайте пробный заказ, посмотрите нехватку в закупках, оформите приход на складе и спишите продукты по заказу. Все данные можно редактировать.

${status?.canUpgrade?'':''}
Технологические карты боксов и блюд

`: `
Попробуйте приложение на готовом меню

Боксы и премиум-сеты, 18 банкетных блюд, напитки, посуда, дополнения и доставка. Учебные цены, составы и поставщики для проверки заказа, склада и закупки.

`; // Preserve the user's disclosure and selection across actual data changes. if(previousGuide.open&&card.querySelector('details'))card.querySelector('details').open=true; const selector=$('ctDemoBox');if(selector&&[...selector.options].some(o=>o.value===previousGuide.selected))selector.value=previousGuide.selected; if(previousGuide.message&&$('ctDemoMessage'))$('ctDemoMessage').textContent=previousGuide.message; card.querySelector('[data-demo-install]')?.addEventListener('click',install); card.querySelector('[data-demo-order]')?.addEventListener('click',createOrder); card.querySelector('[data-demo-ttk]')?.addEventListener('click',()=>showTTK($('ctDemoBox').value)); card.querySelectorAll('[data-demo-go]').forEach(b=>b.addEventListener('click',()=>navigate(b.dataset.demoGo))); } async function install(){try{await window.CateriumTrainingCatalog.setEnabled(true);}catch(error){message(error.message);}} function createOrder(){ if(!writable()||!installed()||(window.CateriumTrainingCatalog&&!window.CateriumTrainingCatalog.enabled()))return; const repo=data()?.orders;if(!repo){message('Приложение ещё загружается. Повторите через несколько секунд.');return;} const all=repo.list(),existing=all.find(o=>o.demoBatch===BATCH); if(existing){message(`Пробный заказ №${existing.id} уже создан. Его можно открыть во вкладке «Заказы».`);return;} const spec=read(KEY,{}).scenario?.lines,items=catalog(); if(!Array.isArray(spec)||spec.length!==3){message('Сценарий недоступен. Добавьте боксы в заказ самостоятельно.');return;} const lines=spec.map(l=>{const box=items.find(b=>String(b.id)===String(l.id));return box?{id:box.id,name:box.name,qty:l.qty,price:(window.CateriumPricing?.price(box)??Number(box?.price||0))}:null}); if(lines.some(l=>!l)){message('Некоторые демо-боксы удалены. Добавьте оставшиеся в заказ самостоятельно.');return;} const total=lines.reduce((s,l)=>s+l.price*l.qty,0),day=new Date();day.setDate(day.getDate()+1); const date=`${day.getFullYear()}-${String(day.getMonth()+1).padStart(2,'0')}-${String(day.getDate()).padStart(2,'0')}`; const id=Math.max(0,...all.map(o=>Number(o.id)||0))+1; repo.replace([...all,{id,event:'Демо: фуршет',date,time:'12:00',contact:'',phone:'',address:'',note:'Учебный заказ для проверки склада и закупки. Автозавершение отключено.',status:'Новый',lines,total,prepayment:0,balance:total,demo:true,demoBatch:BATCH,autoCompletionDisabled:true}],{reason:'trial-demo.order'}); window.renderOrders?.();window.sunRefreshStock?.(); message(`Заказ №${id} на ${money(total)} создан на завтра. Откройте «Закупки», чтобы увидеть нехватку продуктов.`); } function showTTK(id){ const box=catalog().find(b=>String(b.id)===String(id));if(!box?.ttk)return; $('ctDemoTtk')?.remove();const t=box.ttk,dialog=document.createElement('dialog');dialog.id='ctDemoTtk'; const changed=JSON.stringify(box.ingredients)!==JSON.stringify(t.rows.map(r=>[r.name,r.gross,r.unit])); dialog.innerHTML=`
${esc(t.number)} · ${esc(t.basis)}

${esc(box.name)}

${changed?'Исходный выход':'Выход'}: ${num(t.outputGrams)} г${Number(box.category)===6?' · 1 порция':t.pieces?` · ${num(t.pieces)} шт.`:''} · ${Number(box.category)===6?'Цена порции':'Цена бокса'}: ${money((window.CateriumPricing?.price(box)??Number(box?.price||0)))}

${changed?'

Состав изменён. Закупка и списание используют текущий состав из редактора. Ниже показана исходная учебная ТТК.

':''}
${t.rows.map(r=>``).join('')}
Продукт / упаковкаЕд.БруттоНеттоЦена за ед.Сумма
${esc(r.name)}${esc(r.unit)}${num(r.gross)}${num(r.net)}${money(r.unitCost)}${money(r.gross*r.unitCost)}

Продукты и упаковка: ${money(t.ingredientCost)}

Учебные закупочные цены. Работа, доставка и накладные расходы не включены. Расход со склада считается по брутто.

${t.waterGrams?`

В выходе учтено ${num(t.waterGrams)} г воды, поглощённой при приготовлении. Вода не списывается со склада.

`:''}

Приготовление и сборка

    ${t.steps.map(s=>`
  1. ${esc(s)}
  2. `).join('')}

Аллергены: ${t.allergens.length?t.allergens.map(esc).join(', '):'в учебном составе не указаны; уточните по продуктам поставщика'}.

${esc(t.note)}

`; document.body.append(dialog);dialog.querySelectorAll('[data-ttk-close]').forEach(b=>b.onclick=()=>dialog.close()); dialog.querySelector('[data-ttk-edit]').onclick=()=>{dialog.close();window.editBox?.(box.id)}; dialog.addEventListener('close',()=>dialog.remove(),{once:true});dialog.showModal(); } function reset(){epoch++;pending=null;status=null;statusWorkspace='';$('ctTrialDemo')?.remove();$('ctTrainingNotice')?.remove();$('ctDemoTtk')?.remove();} function boot(){ const style=document.createElement('style');style.textContent=`#ctTrialDemo{margin:0 0 18px;padding:18px 22px}#ctTrialDemo p{font-size:13px;line-height:1.5;margin:6px 0 12px;max-width:900px}.ct-demo-heading{display:flex;justify-content:space-between;gap:14px;align-items:flex-start}.ct-demo-heading strong{font-size:18px}.ct-demo-heading h2{font-size:22px;margin:8px 0}.ct-demo-badge{border:1px solid #c3d4bd;border-radius:18px;padding:5px 10px;font-size:12px;white-space:nowrap}.ct-demo-actions{display:flex;gap:10px;align-items:end;flex-wrap:wrap;margin:12px 0}.ct-demo-actions label{min-width:0;max-width:100%;flex:1}.ct-demo-actions select{width:100%;font:inherit;padding:9px}.ct-demo-actions button{max-width:100%}#ctTrialDemo details{font-size:13px;margin-top:14px}#ctTrialDemo summary{cursor:pointer}#ctDemoMessage:empty{display:none}#ctDemoTtk{width:min(860px,calc(100vw - 24px));max-height:90dvh;box-sizing:border-box;overflow:auto;border:1px solid #d4c8b0;border-radius:18px;padding:24px;background:var(--card,#fff);color:var(--text,#27241e)}#ctDemoTtk::backdrop{background:#0008}.ct-demo-table{overflow-x:auto}.ct-demo-table table{border-collapse:collapse;min-width:580px;width:100%;font-size:13px}.ct-demo-table td,.ct-demo-table th{text-align:right;padding:9px 7px;border-bottom:1px solid #ddd}.ct-demo-table th:first-child,.ct-demo-table td:first-child{text-align:left}#ctDemoTtk li{margin:8px 0;line-height:1.5}.ct-demo-notice{background:#fff3d6;color:#604918;padding:12px;border-radius:8px}@media(max-width:600px){#ctTrialDemo{padding:14px}.ct-demo-heading{flex-wrap:wrap}.ct-demo-actions>button{flex:1 1 auto}.ct-demo-actions label{flex-basis:100%}#ctDemoTtk{padding:16px}}#ctTrainingNotice{display:flex;align-items:center;flex-wrap:wrap;gap:4px 6px;margin:0 0 12px;padding:7px 12px;border:1px solid #e6dcc0;border-radius:10px;background:#faf6e9;color:#5f4f25;font-size:12px;line-height:1.4}#ctTrainingNotice button{all:unset;box-sizing:border-box;cursor:pointer;color:#7a5c12;text-decoration:underline;font:inherit}#ctTrainingNotice button:focus-visible{outline:2px solid #b88c2e;outline-offset:2px;border-radius:3px}#ctTrainingSettings #ctTrialDemo{margin:16px 0 0;padding:16px 0 0;border:0;border-top:1px solid var(--sun-ui-border,#deded6);border-radius:0;box-shadow:none;background:none}#ctTrainingSettings #ctTrialDemo .ct-demo-heading strong{font-size:15px}@media print{#ctTrialDemo,#ctTrainingNotice{display:none!important}}`; document.head.append(style); window.addEventListener('sun:cloud-tenant-changing',reset); window.addEventListener('sun:cloud-permissions-changed',()=>{render();refreshStatus()}); window.addEventListener('sun:cloud-state-applied',()=>{render();refreshStatus()}); window.addEventListener('sun:subscription-changed',()=>{statusWorkspace='';render();refreshStatus()}); document.addEventListener('click',e=>{if(e.target.closest('header nav button')){render();refreshStatus()}}); data()?.subscribe('catalog',render);setTimeout(()=>{render();refreshStatus()},1400); } window.CateriumTrialDemo={render,refreshStatus,showTTK}; if(document.readyState==='loading')document.addEventListener('DOMContentLoaded',boot,{once:true});else boot(); })();