(()=>{ '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(){ const c=cloud(),ws=c?.getWorkspace?.()?.id; if(!signedIn()||c?.isSupportMode?.()){status=null;statusWorkspace='';render();return;} if(statusWorkspace===ws||pending)return; const ticket=epoch;pending=ws; try{const result=await c.getClient?.()?.rpc('caterium_trial_demo_status',{p_workspace:ws}); if(ticket!==epoch||c.getWorkspace?.()?.id!==ws)return; if(result?.error)throw result.error; status=result?.data||null;statusWorkspace=ws; }catch(_){status=null;}finally{if(ticket===epoch){pending=null;render();}} } function render(){ const host=$('new');if(!host)return; const items=catalog().filter(b=>b.demo&&b.ttk),active=installed()&&items.length>0; if(!signedIn()||cloud()?.isSupportMode?.()||(!active&&!status?.canInstall)){$('ctTrialDemo')?.remove();return;} let card=$('ctTrialDemo');if(!card){card=document.createElement('section');card.id='ctTrialDemo';card.className='card';host.prepend(card);} const signature=JSON.stringify({active,items:items.map(x=>[x.id,x.name]),can:writable()}); if(card.dataset.signature===signature)return;card.dataset.signature=signature; card.innerHTML=active?`
Демонстрационная база

${items.length} боксов с фото и ТТК · учебные остатки и поставщики

Можно пробовать

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

Технологические карты боксов

`: `
Попробуйте приложение на готовых боксах

10 боксов с фото и ТТК, 43 продукта, 5 учебных поставщиков и начальные остатки.

`; 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(){ if(busy)return;busy=true;const btn=$('ctTrialDemo')?.querySelector('[data-demo-install]');if(btn)btn.disabled=true; message('Загружаю демонстрационную базу…'); try{await cloud().installTrialDemo();status=null;statusWorkspace='';render();message('Готово. Создайте пробный заказ или выберите боксы самостоятельно.');await refreshStatus();} catch(error){message(error?.message||'Не удалось загрузить демо. Повторите попытку.');} finally{busy=false;if(btn?.isConnected)btn.disabled=false;} } function createOrder(){ if(!writable()||!installed())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: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)} г${t.pieces?` · ${num(t.pieces)} шт.`:''} · Цена бокса: ${money(box.price)}

${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.steps.map(s=>`
  1. ${esc(s)}
  2. `).join('')}

Аллергены: ${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();$('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}}@media print{#ctTrialDemo{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(); })();