39 lines
7.0 KiB
React
39 lines
7.0 KiB
React
import React,{useEffect,useState} from 'react';
|
|
import {stockSections,visibleStockSections,stockOperations,availableStockReports} from './stock-menu.js';
|
|
import StockReadWorkspace from './StockReadWorkspace.jsx';
|
|
|
|
export default function StockMenuWorkspace({section,context,can,navigate,api}) {
|
|
const [reportId,setReportId]=useState('balances');
|
|
useEffect(()=>{setReportId('balances');},[context.token]);
|
|
if(!can('company.view'))return <section className="panel"><h1>Stock</h1><p>Seleccione uma empresa autorizada.</p></section>;
|
|
const active=stockSections.find(s=>s.id===section);
|
|
if(!active)return null;
|
|
const operation=stockOperations[section];
|
|
const canRead=Boolean(api&&context.unit&&can('stock.view',context.unit.id));
|
|
// This SGF composition has no stock source, feature configuration or cost permission yet.
|
|
// Do not substitute workshop rights, company rights or purchasing roles for stock rights.
|
|
const reports=availableStockReports({},false),report=reports.find(r=>r.id===reportId)??reports[0];
|
|
const tabs=<nav className="stock-tabs" aria-label="Submenus de stock">{visibleStockSections(can).map(s=><button key={s.id} aria-current={s.id===section?'page':undefined} onClick={()=>navigate(s.id)}>{s.label}</button>)}</nav>;
|
|
return <div className="stock-menu-workspace"><div className="page-title"><p className="eyebrow">STOCK</p><h1>{active.label}</h1><p>{context.company.name}{context.unit?` / ${context.unit.name}`:''}</p></div>{tabs}
|
|
{canRead?<div className="alert home-notice" role="status"><strong>Consulta condicionada à fonte sintética autorizada.</strong><p>Entradas, saídas, transferências e custos continuam indisponíveis. A consulta não altera os saldos de Compras.</p></div>:<div className="alert home-notice" role="status"><strong>Menu em preparação — fonte de stock ainda não ligada ao SGF.</strong><p>Os saldos e movimentos de Compras permanecem na sua aplicação. Aqui não são apresentados como zero, importados ou alterados. Os apontamentos da oficina não são existências de armazém.</p></div>}
|
|
{section==='stock_panel'&&<>
|
|
<section className="panel"><h2>Situação actual</h2><p>Não há indicadores de stock disponíveis nesta composição. Não é possível determinar produtos abaixo do mínimo, entradas/saídas, valor do stock ou mercadoria em trânsito.</p><p>O painel sinalizará situações actuais; os relatórios permitirão investigar os movimentos e o período. Nenhum indicador é calculado a partir de exemplos ilustrativos.</p></section>
|
|
<section className="panel"><h2>Escolher percurso</h2><div className="stock-route-grid">{stockSections.filter(s=>s.id!=='stock_panel').map(s=><button key={s.id} onClick={()=>navigate(s.id)}>{s.label}<span>Consultar o âmbito e o estado de disponibilidade →</span></button>)}</div></section>
|
|
</>}
|
|
{section==='stock_balances'&&canRead&&<StockReadWorkspace key={context.token} api={api} context={context}/>}
|
|
{section==='stock_balances'&&!canRead&&<>
|
|
<section className="panel"><h2>Consulta de existências indisponível</h2><p>Falta a fonte autorizada de produtos, armazéns e saldos desta empresa. Não há uma lista vazia de existências nem um saldo editável.</p><dl className="stock-definitions"><div><dt>Físico</dt><dd>Quantidade efectivamente registada no armazém, incluindo reservado e bloqueado.</dd></div><div><dt>Reservado</dt><dd>Quantidade comprometida com documentos próprios, quando o controlo estiver activo.</dd></div><div><dt>Bloqueado</dt><dd>Quantidade indisponível por condição ou qualidade, sem sobreposição com reservas.</dd></div><div><dt>Disponível</dt><dd>Físico menos reservado e bloqueado. Mercadoria em trânsito não está disponível no destino.</dd></div></dl><p>Se uma dessas parcelas não estiver sustentada, o disponível fica indeterminado; não se usa zero como substituto.</p></section>
|
|
<section className="panel"><h2>Pesquisa e rastreabilidade previstas</h2><p>Produto por código, designação ou código de barras; armazém, categoria e situação de stock. Localização, lote, série e validade só serão apresentados se configurados.</p><p>A ficha dará acesso ao movimento e ao documento original. Diferenças físicas serão tratadas por contagem e ajuste autorizado em Inventário, nunca por edição directa do saldo.</p><button onClick={()=>navigate('stock_reports')}>Ver relatórios de controlo</button></section>
|
|
</>}
|
|
{operation&&<>
|
|
<section className="panel"><h2>{operation.title}</h2><p>{operation.purpose}</p><p className="stock-unavailable">Operação indisponível no SGF. Não há confirmação ou gravação neste ecrã.</p><h3>Campos do percurso previsto</h3><ul>{operation.fields.map(f=><li key={f}>{f}</li>)}</ul><p>Localizações, lotes, séries, validade e câmbio só entram quando o produto e a configuração os exigirem. Não são assumidos por omissão.</p></section>
|
|
<section className="panel"><h2>Etapas previstas</h2><ol>{operation.flow.map(step=><li key={step}>{step}</li>)}</ol><h3>O que já existe e o que falta</h3><p>{operation.existing}</p><p>{operation.missing}</p><p><strong>Prevenção de duplicações:</strong> {operation.control}</p></section>
|
|
</>}
|
|
{section==='stock_reports'&&<>
|
|
<section className="panel"><h2>Relatórios essenciais</h2><label>Relatório<select value={reportId} onChange={e=>setReportId(e.target.value)}>{reports.map(r=><option key={r.id} value={r.id}>{r.label}</option>)}</select></label><h3>{report.label}</h3><p><strong>Base temporal:</strong> {report.basis}.</p><p><strong>Informação prevista:</strong> {report.fields}</p><p role="status"><strong>Consulta indisponível.</strong> {report.missing}</p><p>Não é possível gerar, imprimir ou exportar um relatório sem a sua fonte. A falta de informação não é apresentada como ausência de movimentos.</p></section>
|
|
<section className="panel"><h2>Disponibilidade dos restantes relatórios</h2><p>Valorização exige custos, método configurado e permissão própria. Dados de custos não são carregados por este menu. Relatórios de trânsito, devoluções, lotes, inactividade e diferenças de inventário serão apresentados quando os respectivos percursos estiverem activos.</p><p>A consulta e a exportação terão de preservar os mesmos filtros, autorizações, abertura e fecho. Reservas e bloqueios históricos não serão substituídos por valores actuais.</p></section>
|
|
</>}
|
|
<section className="panel"><h2>Regras comuns do percurso</h2><p>Um rascunho não altera stock. A confirmação revalida permissões e quantidades, tem um único efeito e conserva actor, data, motivo e origem. Movimentos confirmados não são editados ou apagados; correcções exigem operação própria ligada ao original.</p><p>Acesso a este mapa não concede consulta de armazéns, custos ou movimentos. A integração operacional terá autorizações específicas e contexto explícito, preservando as diferenças entre empresa, unidade e armazém.</p></section>
|
|
</div>;
|
|
}
|