att
This commit is contained in:
@@ -7,6 +7,7 @@
|
||||
|
||||
<!-- CSS -->
|
||||
<link rel="stylesheet" type="text/css" href="/style-guide/css/fluig-style-guide.min.css">
|
||||
<link rel="stylesheet" type="text/css" href="compras_design_system.css">
|
||||
<link rel="stylesheet" type="text/css" href="comprasV2.css">
|
||||
<link rel="stylesheet" type="text/css" href="style.css">
|
||||
|
||||
@@ -16,6 +17,7 @@
|
||||
<script src="/resources/js/mustache/mustache-min.js"></script>
|
||||
<script src="/style-guide/js/fluig-style-guide.min.js"></script>
|
||||
<script type="text/javascript" src="/webdesk/vcXMLRPC.js"></script>
|
||||
<script type="text/javascript" src="compras_config.js"></script>
|
||||
<script type="text/javascript" src="compras_digital.js"></script>
|
||||
<script type="text/javascript" src="anexos.js"></script>
|
||||
|
||||
@@ -159,10 +161,61 @@
|
||||
line-height: 1;
|
||||
}
|
||||
|
||||
/* Exibe apenas texto (sem fundo) nos status resumidos */
|
||||
/* Oculta todas as seções de atividade por padrão.
|
||||
O script.js revela apenas a(s) correta(s) via .show().
|
||||
Isso evita que todas apareçam antes do $(document).ready executar. */
|
||||
/* Atividades futuras são ocultadas via JS — não via CSS global */
|
||||
|
||||
/* Tabela de itens dentro do card */
|
||||
.card-compras .table-compras { margin-bottom: 0; }
|
||||
.card-compras { overflow-x: auto; }
|
||||
|
||||
/* ── Accordion de histórico de atividades ─────────────────── */
|
||||
.activity-header {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
gap: 10px;
|
||||
padding: 10px 14px;
|
||||
margin-bottom: 4px;
|
||||
background: #f0f7fb;
|
||||
border: 1px solid #cde0ea;
|
||||
border-radius: 8px;
|
||||
cursor: pointer;
|
||||
transition: background .15s;
|
||||
user-select: none;
|
||||
}
|
||||
.activity-header:hover { background: #deeef7; }
|
||||
.activity-header-check {
|
||||
width: 20px; height: 20px;
|
||||
border-radius: 50%;
|
||||
background: #0e9f6e;
|
||||
color: #fff;
|
||||
font-size: 11px; font-weight: 700;
|
||||
display: flex; align-items: center; justify-content: center;
|
||||
flex-shrink: 0;
|
||||
}
|
||||
.activity-header-titulo {
|
||||
font-size: 13px; font-weight: 700;
|
||||
color: #04506b;
|
||||
}
|
||||
.activity-header-resumo {
|
||||
font-size: 12px; color: #6b7280;
|
||||
flex: 1; overflow: hidden;
|
||||
white-space: nowrap; text-overflow: ellipsis;
|
||||
}
|
||||
.activity-header-caret {
|
||||
font-size: 10px; color: #9ca3af;
|
||||
transition: transform .2s;
|
||||
flex-shrink: 0;
|
||||
}
|
||||
.activity.is-collapsed .activity-header-caret { transform: rotate(-90deg); }
|
||||
.activity.is-collapsed .activity-body { display: none; }
|
||||
.activity.accordion-pronto { margin-bottom: 6px; }
|
||||
/* ──────────────────────────────────────────────────────────── */
|
||||
|
||||
/* Exibe apenas texto (sem fundo) nos cards de resumo do topo — intencional */
|
||||
#statusSCProtheus_label,
|
||||
#statusSC_label,
|
||||
#cotacaoResultado_label {
|
||||
#statusSC_label {
|
||||
background: transparent !important;
|
||||
border-radius: 0 !important;
|
||||
min-height: 0 !important;
|
||||
@@ -199,6 +252,9 @@
|
||||
gap: 12px;
|
||||
align-items: start;
|
||||
}
|
||||
.sc-timeline-layout > div:last-child {
|
||||
align-self: stretch;
|
||||
}
|
||||
|
||||
.sc-timeline-panel {
|
||||
padding: 12px;
|
||||
@@ -723,10 +779,11 @@
|
||||
</div>
|
||||
|
||||
<!-- Painel Itens -->
|
||||
<div class="panel panel-default">
|
||||
<div class="panel-heading"><strong>Itens</strong></div>
|
||||
<div class="panel-body">
|
||||
<table id="tbItens" tablename="tbItens" class="table table-bordered" noaddbutton="true" nodeletebutton="true">
|
||||
<div class="card-compras">
|
||||
<div class="card-compras-header">
|
||||
<span class="card-compras-title"><i class="fluigicon fluigicon-shopping-cart" aria-hidden="true"></i> Itens da Solicitação</span>
|
||||
</div>
|
||||
<table id="tbItens" tablename="tbItens" class="table-compras" noaddbutton="true" nodeletebutton="true">
|
||||
<thead>
|
||||
<tr>
|
||||
<th>#</th>
|
||||
@@ -760,7 +817,6 @@
|
||||
</tr>
|
||||
</tbody>
|
||||
</table>
|
||||
</div>
|
||||
</div>
|
||||
<!-- Linha 5 - Anexo + Observações -->
|
||||
<div class="row">
|
||||
@@ -835,10 +891,10 @@
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div><!-- /activity-4 -->
|
||||
</div><!-- /activity-121 -->
|
||||
|
||||
<!-- DADOS DO DOCUMENTO -->
|
||||
<div class="activity activity-114">
|
||||
<div class="activity activity-18 activity-121 activity-24">
|
||||
<div class="row">
|
||||
<div class="col-md-12">
|
||||
<h2><i class="flaticon flaticon-totvs-forms icon-md" aria-hidden="true"></i>Dados da Solicitação</h2>
|
||||
@@ -866,11 +922,11 @@
|
||||
<div class="sc-secondary-grid">
|
||||
<div class="sc-info sc-info--secondary">
|
||||
<div class="sc-label">Status Cadastro</div>
|
||||
<span class="sc-value badge bg-secondary" id="statusSCProtheus_label">-</span>
|
||||
<span class="sc-value badge-status badge-waiting" id="statusSCProtheus_label">-</span>
|
||||
</div>
|
||||
<div class="sc-info sc-info--secondary">
|
||||
<div class="sc-label">Andamento</div>
|
||||
<span class="sc-value badge bg-secondary" id="statusSC_label">-</span>
|
||||
<span class="sc-value badge-status badge-waiting" id="statusSC_label">-</span>
|
||||
</div>
|
||||
<div class="sc-info sc-info--secondary">
|
||||
<div class="sc-label">Emissão</div>
|
||||
@@ -885,39 +941,41 @@
|
||||
<ul class="sc-timeline" id="scTimeline"></ul>
|
||||
</div>
|
||||
|
||||
<div class="sc-pedido-track">
|
||||
<div class="sc-cotacao-head">
|
||||
<h4 class="sc-timeline-title" style="margin:0;">Aprovação do pedido</h4>
|
||||
<span class="sc-value badge bg-secondary" id="pedidoRastreio_label">Sem pedido</span>
|
||||
<div style="display:flex; flex-direction:column; gap:12px; min-width:0;">
|
||||
<div class="sc-cotacao-track" style="margin-top:0;">
|
||||
<div class="sc-cotacao-head">
|
||||
<h4 class="sc-timeline-title" style="margin:0;">Acompanhamento da cotação</h4>
|
||||
<span class="badge-status badge-waiting" id="cotacaoResultado_label">Sem cotação</span>
|
||||
</div>
|
||||
<div class="sc-cotacao-kpis" id="cotacaoResultadoResumo">
|
||||
<div class="sc-cotacao-kpi">
|
||||
<span class="sc-cotacao-kpi-label">Cotações</span>
|
||||
<span class="sc-cotacao-kpi-value">0</span>
|
||||
</div>
|
||||
<div class="sc-cotacao-kpi">
|
||||
<span class="sc-cotacao-kpi-label">Com pedido</span>
|
||||
<span class="sc-cotacao-kpi-value">0</span>
|
||||
</div>
|
||||
<div class="sc-cotacao-kpi">
|
||||
<span class="sc-cotacao-kpi-label">Menor total</span>
|
||||
<span class="sc-cotacao-kpi-value">-</span>
|
||||
</div>
|
||||
</div>
|
||||
<div class="sc-cotacao-grid" id="cotacaoResultadoLista">
|
||||
<div class="sc-cotacao-empty">Aguardando vínculo da cotação na SC.</div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="sc-pedido-resumo" id="pedidoRastreioResumo">Sem pedido vinculado.</div>
|
||||
<div class="sc-pedido-assinaturas" id="pedidoRastreioAssinaturas">
|
||||
<div class="sc-cotacao-empty">Sem assinaturas para exibir.</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="sc-cotacao-track">
|
||||
<div class="sc-cotacao-head">
|
||||
<h4 class="sc-timeline-title" style="margin:0;">Acompanhamento da cotação</h4>
|
||||
<span class="sc-value badge bg-secondary" id="cotacaoResultado_label">Sem cotação</span>
|
||||
</div>
|
||||
<div class="sc-cotacao-kpis" id="cotacaoResultadoResumo">
|
||||
<div class="sc-cotacao-kpi">
|
||||
<span class="sc-cotacao-kpi-label">Cotações</span>
|
||||
<span class="sc-cotacao-kpi-value">0</span>
|
||||
<div class="sc-pedido-track" style="margin-top:0;">
|
||||
<div class="sc-cotacao-head">
|
||||
<h4 class="sc-timeline-title" style="margin:0;">Aprovação do pedido</h4>
|
||||
<span class="badge-status badge-waiting" id="pedidoRastreio_label">Sem pedido</span>
|
||||
</div>
|
||||
<div class="sc-pedido-resumo" id="pedidoRastreioResumo">Sem pedido vinculado.</div>
|
||||
<div class="sc-pedido-assinaturas" id="pedidoRastreioAssinaturas">
|
||||
<div class="sc-cotacao-empty">Sem assinaturas para exibir.</div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="sc-cotacao-kpi">
|
||||
<span class="sc-cotacao-kpi-label">Com pedido</span>
|
||||
<span class="sc-cotacao-kpi-value">0</span>
|
||||
</div>
|
||||
<div class="sc-cotacao-kpi">
|
||||
<span class="sc-cotacao-kpi-label">Menor total</span>
|
||||
<span class="sc-cotacao-kpi-value">-</span>
|
||||
</div>
|
||||
</div>
|
||||
<div class="sc-cotacao-grid" id="cotacaoResultadoLista">
|
||||
<div class="sc-cotacao-empty">Aguardando vínculo da cotação na SC.</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
@@ -1,424 +1,39 @@
|
||||
$(document).ready(function () {
|
||||
if ($("#formMode").val() == "VIEW") {
|
||||
showAndBlock(["all"]);
|
||||
} else {
|
||||
var activity = $("#activity").val();
|
||||
var requestDate = getCurrentDate();
|
||||
/**
|
||||
* compras.js
|
||||
*
|
||||
* Funções de controle da tabela de itens (tbItens) e cálculo de totais.
|
||||
* As demais funções deste arquivo (modal de produtos, zoom handlers, activity manager)
|
||||
* foram consolidadas em compras_digital.js e script.js.
|
||||
*/
|
||||
|
||||
$(".activity").hide();
|
||||
$(".activity-" + activity).show();
|
||||
|
||||
// Atividade 4: Abertura
|
||||
if (activity == 4) {
|
||||
$("#dataNec").val(requestDate[0]); // já coloca a data de hoje
|
||||
toggleBotaoAddItem();
|
||||
|
||||
// Atividade 6: Validação do Centro de Custo
|
||||
} else if (activity == 5) {
|
||||
showAndBlock([4]); // bloqueia os campos da abertura
|
||||
$("#userValidacaoGestor").val($("#currentUserName").val());
|
||||
$("#dataValidacaoGestor").val(requestDate[0] + " - " + requestDate[1]);
|
||||
|
||||
if ($("#justificativaDecisaoGestor").val() == "") {
|
||||
$(".justificativa-activity-4").hide();
|
||||
}
|
||||
}
|
||||
}});
|
||||
|
||||
$(document).ready(function () {
|
||||
try {
|
||||
FLUIGC.calendar('#dataNec');
|
||||
} catch (e) {
|
||||
console.warn("Erro ao iniciar calendário:", e);
|
||||
}
|
||||
|
||||
toggleBotaoAddItem(); // inicia escondido
|
||||
|
||||
/* ========= Eventos ========= */
|
||||
$('#precoRef, #quantidade').on('input', recalcTotal);
|
||||
|
||||
$('#qtdMais').on('click', function () {
|
||||
let v = parseInt($('#quantidade').val() || '0', 10);
|
||||
$('#quantidade').val(v + 1);
|
||||
recalcTotal();
|
||||
});
|
||||
|
||||
$('#qtdMenos').on('click', function () {
|
||||
let v = parseInt($('#quantidade').val() || '0', 10);
|
||||
v = Math.max(0, v - 1);
|
||||
$('#quantidade').val(v);
|
||||
recalcTotal();
|
||||
});
|
||||
|
||||
$('#btnBuscaProd').on('click', consultarProdutos);
|
||||
$('#btnLimpaProd').on('click', limparCamposPrincipais);
|
||||
$('#btnAddItem').on('click', adicionarItem);
|
||||
});
|
||||
|
||||
function showAndBlock(activity) {
|
||||
for (var i = 0; i < activity.length; i++) {
|
||||
$(".activity-" + activity[i]).show();
|
||||
$(".hideButton").hide();
|
||||
$(".activity-" + activity[i] + " :input").each(function () {
|
||||
$(this).attr("readonly", "readonly")
|
||||
.css("background-color", "#eee")
|
||||
.children("option:not(:selected)").prop("disabled", true);
|
||||
|
||||
if ($(this).is(":checkbox") || $(this).is(":radio")) {
|
||||
$(this).attr("disabled", true);
|
||||
}
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
function getCurrentDate() {
|
||||
var newDate = new Date();
|
||||
var h = newDate.getHours();
|
||||
if (h < 10) {
|
||||
h = "0" + h;
|
||||
}
|
||||
var m = newDate.getMinutes();
|
||||
if (m < 10) {
|
||||
m = "0" + m;
|
||||
}
|
||||
var hour = h + ":" + m; // + ":" + s;
|
||||
var day = newDate.getDate();
|
||||
if (day < 10) {
|
||||
day = "0" + day;
|
||||
}
|
||||
var month = newDate.getMonth() + 1;
|
||||
if (month < 10) {
|
||||
month = "0" + month;
|
||||
}
|
||||
newDate = day + "/" + month + "/" + newDate.getFullYear();
|
||||
var currentDate = [newDate, hour];
|
||||
return currentDate;
|
||||
}
|
||||
|
||||
|
||||
function toggleBotaoAddItem() {
|
||||
const temProduto = $('#produtoCod').val() || $('#DescoProduto').val();
|
||||
if (temProduto && temProduto.trim() !== "") {
|
||||
$('#btnAddItem').show();
|
||||
} else {
|
||||
$('#btnAddItem').hide();
|
||||
}
|
||||
}
|
||||
|
||||
function setSelectedZoomItem(selectedItem) {
|
||||
if (selectedItem.inputId === "estabelecimento") {
|
||||
// joga o código da filial (cnpj, etc.)
|
||||
$("#filialDesc").val(selectedItem.CNPJ); // supondo que o dataset dsSysCompany devolva o campo CNPJ
|
||||
$("#filialest").val(selectedItem.ESTADO); // supondo que o dataset dsSysCompany devolva o campo ESTADO
|
||||
}
|
||||
if (selectedItem.inputId === "centroCusto") {
|
||||
// joga o nome do gestor
|
||||
$("#gestorCentroCusto").val(selectedItem.gestorCentroCusto); // supondo que o dataset dsCentroCusto devolva o campo GestorCentroCusto
|
||||
}
|
||||
}
|
||||
|
||||
function removedZoomItem(removedItem) {
|
||||
if (removedItem.inputId === "estabelecimento") {
|
||||
// Quando remover a empresa, limpa os campos relacionados
|
||||
$("#filialDesc").val('');
|
||||
$("#filialest").val('');
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/* ========= Config ========= */
|
||||
const DATASET_PRODUTOS = "dsProd"; // dataset de produtos
|
||||
let todosProdutos = [];
|
||||
let paginaAtual = 1;
|
||||
const itensPorPagina = 10;
|
||||
|
||||
/* ========= Utils ========= */
|
||||
function escapeHTML(txt) {
|
||||
return $('<div>').text(txt == null ? '' : String(txt)).html();
|
||||
}
|
||||
|
||||
function brMoneyToFloat(v) {
|
||||
if (!v) return 0;
|
||||
return parseFloat(String(v).replace(/\./g, '').replace(',', '.')) || 0;
|
||||
}
|
||||
|
||||
function floatToBRL(n) {
|
||||
try {
|
||||
return new Intl.NumberFormat('pt-BR', { style: 'currency', currency: 'BRL' }).format(n || 0);
|
||||
} catch (_) {
|
||||
return 'R$ ' + (n || 0).toFixed(2).replace('.', ',');
|
||||
}
|
||||
}
|
||||
|
||||
/* ========= Modal Consulta Produtos ========= */
|
||||
function consultarProdutos() {
|
||||
FLUIGC.modal({
|
||||
title: 'Consulta de Produtos',
|
||||
content:
|
||||
'<div id="buscaProduto" style="margin-bottom:10px;">' +
|
||||
'<input type="text" id="filtroDescricao" class="form-control" placeholder="Buscar por descrição..." onkeyup="filtrarProdutos()">' +
|
||||
'</div>' +
|
||||
'<div id="listaProdutos"></div>' +
|
||||
'<div id="paginacaoProdutos" style="margin-top:10px; text-align:center;"></div>',
|
||||
id: 'modalConsultaProdutos',
|
||||
size: 'large',
|
||||
actions: [{ 'label': 'Fechar', 'autoClose': true }]
|
||||
}, function (err) {
|
||||
if (!err) carregaListaProdutos();
|
||||
});
|
||||
}
|
||||
|
||||
function carregaListaProdutos(filtro) {
|
||||
// Só chama o dataset se ainda não carregou nada
|
||||
if (todosProdutos.length === 0) {
|
||||
let dataset = DatasetFactory.getDataset(DATASET_PRODUTOS, null, null, null);
|
||||
todosProdutos = dataset && dataset.values ? dataset.values : [];
|
||||
console.log("Produtos carregados do dataset:", todosProdutos.length);
|
||||
}
|
||||
|
||||
paginaAtual = 1;
|
||||
renderizaProdutos(filtro);
|
||||
}
|
||||
|
||||
|
||||
function filtrarProdutos() {
|
||||
paginaAtual = 1;
|
||||
renderizaProdutos();
|
||||
}
|
||||
|
||||
function renderizaProdutos(filtro) {
|
||||
filtro = (filtro || $('#filtroDescricao').val() || '').toLowerCase();
|
||||
|
||||
// Agora filtra no cache (sem chamar dataset de novo)
|
||||
const produtosFiltrados = todosProdutos.filter(p =>
|
||||
(p.descricao || '').toLowerCase().includes(filtro) ||
|
||||
(p.codigo || '').toLowerCase().includes(filtro) ||
|
||||
(p.medida || '').toLowerCase().includes(filtro)
|
||||
);
|
||||
|
||||
const inicio = (paginaAtual - 1) * itensPorPagina;
|
||||
const fim = inicio + itensPorPagina;
|
||||
const produtosPagina = produtosFiltrados.slice(inicio, fim);
|
||||
|
||||
let html = `
|
||||
<table class="table table-striped">
|
||||
<thead>
|
||||
<tr>
|
||||
<th>Codigo</th>
|
||||
<th>Descricao</th>
|
||||
<th>UM</th>
|
||||
<th>Ultimo Preco</th>
|
||||
<th>Acao</th>
|
||||
</tr>
|
||||
</thead>
|
||||
<tbody>
|
||||
`;
|
||||
|
||||
if (produtosPagina.length === 0) {
|
||||
html += `
|
||||
<tr>
|
||||
<td colspan="5" class="text-center text-muted">
|
||||
Nenhum produto encontrado
|
||||
</td>
|
||||
</tr>`;
|
||||
} else {
|
||||
produtosPagina.forEach(produto => {
|
||||
const codigo = escapeHTML(produto['codigo']);
|
||||
const descricao = escapeHTML(produto['descricao']);
|
||||
const um = escapeHTML(produto['medida'] || '');
|
||||
const preco = produto['ultimoPreco'] || '0,00';
|
||||
|
||||
html += `
|
||||
<tr>
|
||||
<td>${codigo}</td>
|
||||
<td>${descricao}</td>
|
||||
<td>${um}</td>
|
||||
<td>${preco}</td>
|
||||
<td>
|
||||
<button class="btn btn-sm btn-success selecionar-produto"
|
||||
data-codigo="${codigo}"
|
||||
data-descricao="${descricao}"
|
||||
data-preco="${preco}">
|
||||
Selecionar
|
||||
</button>
|
||||
</td>
|
||||
</tr>`;
|
||||
});
|
||||
}
|
||||
|
||||
html += `</tbody></table>`;
|
||||
$('#listaProdutos').html(html);
|
||||
|
||||
renderizaPaginacao(produtosFiltrados.length);
|
||||
}
|
||||
|
||||
|
||||
|
||||
function renderizaPaginacao(totalItens) {
|
||||
const totalPaginas = Math.ceil(totalItens / itensPorPagina);
|
||||
let html = '';
|
||||
if (totalPaginas > 1) {
|
||||
if (paginaAtual > 1) {
|
||||
html += '<button class="btn btn-sm btn-default" onclick="mudarPagina(' + (paginaAtual - 1) + ')">Anterior</button> ';
|
||||
}
|
||||
html += ' Pagina ' + paginaAtual + ' de ' + totalPaginas + ' ';
|
||||
if (paginaAtual < totalPaginas) {
|
||||
html += '<button class="btn btn-sm btn-default" onclick="mudarPagina(' + (paginaAtual + 1) + ')">Proxima</button>';
|
||||
}
|
||||
}
|
||||
$('#paginacaoProdutos').html(html);
|
||||
}
|
||||
|
||||
function mudarPagina(n) {
|
||||
paginaAtual = n;
|
||||
renderizaProdutos();
|
||||
}
|
||||
|
||||
/* ========= Seleção ========= */
|
||||
function selecionarProduto(codigo, descricao, preco) {
|
||||
$('#produtoCod').val(codigo);
|
||||
$('#DescoProduto').val(codigo + ' - ' + descricao);
|
||||
$('#ultimoPreco').val(preco);
|
||||
|
||||
FLUIGC.toast({ title: 'Produto', message: 'Selecionado: ' + descricao, type: 'success' });
|
||||
$('#modalConsultaProdutos').modal('hide');
|
||||
|
||||
toggleBotaoAddItem(); // 👈 mostra botão
|
||||
}
|
||||
|
||||
/* ========= Eventos delegados ========= */
|
||||
$(document).on('click', '.selecionar-produto', function () {
|
||||
const codigo = $(this).data('codigo');
|
||||
const descricao = $(this).data('descricao');
|
||||
const preco = $(this).data('preco');
|
||||
selecionarProduto(codigo, descricao, preco);
|
||||
});
|
||||
|
||||
// Digitação em Qtd ou Preço Ref → recalcula automaticamente
|
||||
$(document).on('input', 'input[name^="qtd___"], input[name^="Refpreco___"]', function () {
|
||||
recalcLinha(this);
|
||||
});
|
||||
|
||||
/* ========= Total / Quantidade ========= */
|
||||
function recalcTotal() {
|
||||
const q = parseFloat($('#quantidade').val() || '0');
|
||||
const p = brMoneyToFloat($('#precoRef').val());
|
||||
const t = (q * p) || 0;
|
||||
$('#total').val(floatToBRL(t));
|
||||
}
|
||||
|
||||
/* ========= Index das linhas ========= */
|
||||
function atualizarIndex() {
|
||||
$('#tbItens tbody tr.tableRow').each(function (i) {
|
||||
if (!$(this).is('[detail=true]')) {
|
||||
$(this).find('.tableIndex').text(i);
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
/* ========= Totais da tabela ========= */
|
||||
/* ========= Totais da tabela de itens ========= */
|
||||
function atualizarTotais() {
|
||||
let totalItens = 0;
|
||||
let totalGeral = 0;
|
||||
// Percorre as linhas da tabela somando qtd * preço de referência
|
||||
var totalGeral = 0;
|
||||
|
||||
// Pega todos os valores da tabela
|
||||
const dadosTabela = $('#tbItens').find('input').serializeArray();
|
||||
$('#tbItens tbody tr.tableRow:not([detail=true])').each(function () {
|
||||
var qtd = parseFloat($(this).find('input[name^="qtd___"]').val()) || 0;
|
||||
var preco = brMoneyToFloat($(this).find('input[name^="Refpreco___"]').val());
|
||||
var total = qtd * preco;
|
||||
|
||||
// Transforma em objeto chave:valor para fácil acesso
|
||||
const mapValores = {};
|
||||
dadosTabela.forEach(item => {
|
||||
mapValores[item.name] = item.value;
|
||||
});
|
||||
$(this).find('input[name^="totalValor___"]').val(floatToBRL(total));
|
||||
totalGeral += total;
|
||||
});
|
||||
|
||||
// Percorre por linha (cada linha tem um sufixo ___1, ___2...)
|
||||
let idx = 1;
|
||||
while (mapValores['qtd___' + idx] !== undefined) {
|
||||
const qtd = parseFloat(mapValores['qtd___' + idx] || 0);
|
||||
const preco = brMoneyToFloat(mapValores['Refpreco___' + idx] || "0");
|
||||
const total = qtd * preco;
|
||||
|
||||
totalItens += qtd;
|
||||
totalGeral += total;
|
||||
|
||||
// Atualiza campo total da linha
|
||||
if ($(`#totalValor___${idx}`).length) {
|
||||
$(`#totalValor___${idx}`).val(floatToBRL(total));
|
||||
}
|
||||
|
||||
idx++;
|
||||
}
|
||||
|
||||
// Atualiza rodapé
|
||||
$('#totalItens').val(totalItens);
|
||||
$('#totalGeral').val(floatToBRL(totalGeral));
|
||||
$('#totalGeral').val(floatToBRL(totalGeral));
|
||||
$('#totalItens').val($('#tbItens tbody tr.tableRow:not([detail=true])').length);
|
||||
}
|
||||
|
||||
/* ========= Recalcula uma linha ========= */
|
||||
/* ========= Recalcula o total de uma linha ========= */
|
||||
function recalcLinha(el) {
|
||||
const $linha = $(el).closest('tr');
|
||||
const qtd = parseFloat($linha.find('input[name^="qtd___"]').val() || '0');
|
||||
const preco = brMoneyToFloat($linha.find('input[name^="Refpreco___"]').val() || '0');
|
||||
const total = qtd * preco;
|
||||
|
||||
$linha.find('input[name^="totalValor___"]').val(floatToBRL(total));
|
||||
atualizarTotais();
|
||||
}
|
||||
|
||||
/* ========= Remover linha ========= */
|
||||
function fnWdkRemoveChild(el) {
|
||||
$(el).closest('tr').remove();
|
||||
atualizarIndex();
|
||||
atualizarTotais();
|
||||
}
|
||||
|
||||
/* ========= Adicionar Item ========= */
|
||||
function adicionarItem() {
|
||||
const cod = $('#produtoCod').val();
|
||||
const desc = $('#DescoProduto').val();
|
||||
const ult = $('#ultimoPreco').val() || '0,00';
|
||||
const qtd = $('#quantidade').val();
|
||||
const prec = $('#precoRef').val();
|
||||
const tot = $('#total').val();
|
||||
const dataN = $('#dataNec').val();
|
||||
|
||||
if (!cod) {
|
||||
FLUIGC.toast({ title: 'Atenção', message: 'Selecione um produto/serviço', type: 'warning' });
|
||||
return;
|
||||
}
|
||||
|
||||
const idx = wdkAddChild('tbItens');
|
||||
|
||||
setTimeout(() => {
|
||||
$('input[name="Codproduto___' + idx + '"]').val(cod);
|
||||
|
||||
const somenteDesc = desc.includes('-') ? desc.split('-').slice(1).join('-').trim() : desc;
|
||||
$('input[name="produtoDesc___' + idx + '"]').val(somenteDesc);
|
||||
|
||||
$('input[name="ultimoPrecoItem___' + idx + '"]').val(ult);
|
||||
$('input[name="qtd___' + idx + '"]').val(qtd).on('input', function () { recalcLinha(this); });
|
||||
$('input[name="Refpreco___' + idx + '"]').val(prec).on('input', function () { recalcLinha(this); });
|
||||
$('input[name="totalValor___' + idx + '"]').val(tot);
|
||||
$('input[name="dataNecItem___' + idx + '"]').val(dataN);
|
||||
|
||||
atualizarIndex();
|
||||
var $linha = $(el).closest('tr');
|
||||
var qtd = parseFloat($linha.find('input[name^="qtd___"]').val()) || 0;
|
||||
var preco = brMoneyToFloat($linha.find('input[name^="Refpreco___"]').val());
|
||||
$linha.find('input[name^="totalValor___"]').val(floatToBRL(qtd * preco));
|
||||
atualizarTotais();
|
||||
}, 0);
|
||||
|
||||
FLUIGC.toast({ title: 'Item', message: 'Adicionado à lista', type: 'success' });
|
||||
|
||||
limparCamposPrincipais();
|
||||
}
|
||||
|
||||
/* ========= Limpar campos principais ========= */
|
||||
function limparCamposPrincipais() {
|
||||
$('#produtoCod, #DescoProduto').val('');
|
||||
$('#ultimoPreco').val('0,00');
|
||||
$('#quantidade').val('0');
|
||||
$('#precoRef').val('0,00');
|
||||
$('#total').val('R$ 0,00');
|
||||
$('#fnComprovante').val('');
|
||||
|
||||
|
||||
toggleBotaoAddItem(); // 👈 mostra botão
|
||||
}
|
||||
/* ========= Delegação de eventos de preço/quantidade ========= */
|
||||
$(document).on('input', 'input[name^="qtd___"], input[name^="Refpreco___"]', function () {
|
||||
recalcLinha(this);
|
||||
});
|
||||
|
||||
@@ -0,0 +1,29 @@
|
||||
/**
|
||||
* compras_config.js — Configurações centralizadas do formulário Compras Digital
|
||||
* Carregado pelo Fluig junto com os demais scripts do formulário.
|
||||
* Compatível com todos os browsers suportados pelo Fluig 1.8.x.
|
||||
*/
|
||||
|
||||
var ComprasConfig = {
|
||||
datasets: {
|
||||
produtos: "dsComprasProdutos",
|
||||
filiais: "dsFiliais",
|
||||
centroCusto:"ds_centroCusto",
|
||||
condPag: "ds_condPag"
|
||||
},
|
||||
ui: {
|
||||
itensPorPagina: 10
|
||||
},
|
||||
workflow: {
|
||||
activities: {
|
||||
ABERTURA: [0, 1],
|
||||
VALIDACAO_GESTOR:[4],
|
||||
VALIDACAO_CC: [6],
|
||||
COTACAO: [57],
|
||||
REALIZACAO: [31],
|
||||
RECEBIMENTO: [18],
|
||||
PROBLEMA: [24],
|
||||
VALIDACAO_DIR: [121]
|
||||
}
|
||||
}
|
||||
};
|
||||
@@ -0,0 +1,244 @@
|
||||
/**
|
||||
* compras_design_system.css
|
||||
* Design system enterprise para o formulário Compras Digital — Ginseng
|
||||
* Compatível com Fluig 1.8.x (Bootstrap 3 base)
|
||||
*/
|
||||
|
||||
/* ═══════════════════════════════════════════
|
||||
TOKENS
|
||||
═══════════════════════════════════════════ */
|
||||
:root {
|
||||
--clr-primary: #04506b;
|
||||
--clr-primary-dark: #033a50;
|
||||
--clr-primary-light: #e8f4f8;
|
||||
--clr-success: #0e9f6e;
|
||||
--clr-warning: #d97706;
|
||||
--clr-danger: #e02424;
|
||||
--clr-info: #0694a2;
|
||||
--clr-neutral: #6b7280;
|
||||
--clr-bg: #f9fafb;
|
||||
--clr-surface: #ffffff;
|
||||
--clr-border: #e5e7eb;
|
||||
--clr-text: #111827;
|
||||
--clr-text-muted: #6b7280;
|
||||
--radius-sm: 4px;
|
||||
--radius-md: 8px;
|
||||
--radius-lg: 12px;
|
||||
--shadow-sm: 0 1px 3px rgba(0,0,0,.08);
|
||||
--shadow-md: 0 4px 12px rgba(0,0,0,.12);
|
||||
}
|
||||
|
||||
/* ═══════════════════════════════════════════
|
||||
BADGES DE STATUS
|
||||
═══════════════════════════════════════════ */
|
||||
.badge-status {
|
||||
display: inline-flex;
|
||||
align-items: center;
|
||||
gap: 4px;
|
||||
padding: 3px 10px;
|
||||
border-radius: 99px;
|
||||
font-size: 11px;
|
||||
font-weight: 600;
|
||||
text-transform: uppercase;
|
||||
letter-spacing: .4px;
|
||||
white-space: nowrap;
|
||||
}
|
||||
.badge-pending { background: #fef3c7; color: #92400e; }
|
||||
.badge-approved { background: #d1fae5; color: #065f46; }
|
||||
.badge-rejected { background: #fee2e2; color: #991b1b; }
|
||||
.badge-processing { background: #dbeafe; color: #1e40af; }
|
||||
.badge-blocked { background: #fce7f3; color: #9d174d; }
|
||||
.badge-waiting { background: #f3f4f6; color: #374151; }
|
||||
|
||||
/* ═══════════════════════════════════════════
|
||||
CARDS
|
||||
═══════════════════════════════════════════ */
|
||||
.card-compras {
|
||||
background: var(--clr-surface);
|
||||
border: 1px solid var(--clr-border);
|
||||
border-radius: var(--radius-md);
|
||||
padding: 16px 20px;
|
||||
margin-bottom: 16px;
|
||||
box-shadow: var(--shadow-sm);
|
||||
}
|
||||
.card-compras-header {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: space-between;
|
||||
margin-bottom: 12px;
|
||||
padding-bottom: 12px;
|
||||
border-bottom: 1px solid var(--clr-border);
|
||||
}
|
||||
.card-compras-title {
|
||||
font-size: 13px;
|
||||
font-weight: 600;
|
||||
color: var(--clr-primary);
|
||||
margin: 0;
|
||||
text-transform: uppercase;
|
||||
letter-spacing: .5px;
|
||||
}
|
||||
|
||||
/* ═══════════════════════════════════════════
|
||||
TABELA ENTERPRISE
|
||||
═══════════════════════════════════════════ */
|
||||
.table-compras {
|
||||
width: 100%;
|
||||
border-collapse: collapse;
|
||||
font-size: 13px;
|
||||
}
|
||||
.table-compras th {
|
||||
background: var(--clr-primary-light);
|
||||
color: var(--clr-primary-dark);
|
||||
font-weight: 600;
|
||||
font-size: 12px;
|
||||
text-transform: uppercase;
|
||||
letter-spacing: .4px;
|
||||
padding: 8px 12px;
|
||||
border-bottom: 2px solid var(--clr-primary);
|
||||
white-space: nowrap;
|
||||
}
|
||||
.table-compras td {
|
||||
padding: 8px 12px;
|
||||
border-bottom: 1px solid var(--clr-border);
|
||||
vertical-align: middle;
|
||||
color: var(--clr-text);
|
||||
}
|
||||
.table-compras tbody tr:hover {
|
||||
background: var(--clr-primary-light);
|
||||
transition: background .15s;
|
||||
}
|
||||
.table-compras tbody tr:last-child td { border-bottom: none; }
|
||||
|
||||
/* ═══════════════════════════════════════════
|
||||
TIMELINE DE APROVAÇÃO
|
||||
═══════════════════════════════════════════ */
|
||||
.approval-timeline {
|
||||
position: relative;
|
||||
padding-left: 28px;
|
||||
}
|
||||
.approval-timeline::before {
|
||||
content: "";
|
||||
position: absolute;
|
||||
left: 11px; top: 0; bottom: 0;
|
||||
width: 2px;
|
||||
background: var(--clr-border);
|
||||
}
|
||||
.timeline-step { position: relative; margin-bottom: 20px; }
|
||||
.timeline-dot {
|
||||
position: absolute;
|
||||
left: -28px; top: 2px;
|
||||
width: 22px; height: 22px;
|
||||
border-radius: 50%;
|
||||
border: 2px solid var(--clr-border);
|
||||
background: var(--clr-surface);
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
font-size: 10px;
|
||||
font-weight: 700;
|
||||
color: var(--clr-neutral);
|
||||
}
|
||||
.timeline-step.done .timeline-dot { background: var(--clr-success); border-color: var(--clr-success); color: #fff; }
|
||||
.timeline-step.active .timeline-dot { background: var(--clr-primary); border-color: var(--clr-primary); color: #fff; }
|
||||
.timeline-step.blocked .timeline-dot { background: var(--clr-danger); border-color: var(--clr-danger); color: #fff; }
|
||||
.timeline-step.pending .timeline-dot { background: #fff; border-color: var(--clr-warning); color: var(--clr-warning); }
|
||||
.timeline-label { font-size: 13px; font-weight: 600; color: var(--clr-text); line-height: 1.3; }
|
||||
.timeline-meta { font-size: 11px; color: var(--clr-text-muted); margin-top: 2px; }
|
||||
|
||||
/* ═══════════════════════════════════════════
|
||||
EMPTY STATE
|
||||
═══════════════════════════════════════════ */
|
||||
.empty-state {
|
||||
text-align: center;
|
||||
padding: 32px 16px;
|
||||
color: var(--clr-text-muted);
|
||||
}
|
||||
.empty-state-icon { font-size: 40px; margin-bottom: 12px; opacity: .5; }
|
||||
.empty-state-title { font-size: 15px; font-weight: 600; color: var(--clr-text); margin-bottom: 4px; }
|
||||
.empty-state-desc { font-size: 13px; }
|
||||
|
||||
/* ═══════════════════════════════════════════
|
||||
SKELETON LOADING
|
||||
═══════════════════════════════════════════ */
|
||||
.skeleton {
|
||||
background: linear-gradient(90deg, #f3f4f6 25%, #e5e7eb 50%, #f3f4f6 75%);
|
||||
background-size: 200% 100%;
|
||||
animation: skeleton-shimmer 1.4s infinite;
|
||||
border-radius: var(--radius-sm);
|
||||
height: 14px;
|
||||
margin-bottom: 8px;
|
||||
}
|
||||
.skeleton-wide { width: 80%; }
|
||||
.skeleton-short { width: 40%; }
|
||||
@keyframes skeleton-shimmer {
|
||||
0% { background-position: 200% 0; }
|
||||
100% { background-position: -200% 0; }
|
||||
}
|
||||
|
||||
/* ═══════════════════════════════════════════
|
||||
PAINEL DE STATUS DA SC (existente — melhorado)
|
||||
═══════════════════════════════════════════ */
|
||||
.sc-status-panel {
|
||||
border-radius: var(--radius-lg) !important;
|
||||
border-color: var(--clr-border) !important;
|
||||
background: var(--clr-bg) !important;
|
||||
box-shadow: var(--shadow-sm) !important;
|
||||
}
|
||||
.sc-status-panel .sc-field-label {
|
||||
font-size: 10px;
|
||||
font-weight: 600;
|
||||
text-transform: uppercase;
|
||||
letter-spacing: .5px;
|
||||
color: var(--clr-text-muted);
|
||||
margin-bottom: 2px;
|
||||
}
|
||||
.sc-status-panel .sc-field-value {
|
||||
font-size: 13px;
|
||||
font-weight: 500;
|
||||
color: var(--clr-text);
|
||||
}
|
||||
|
||||
/* ═══════════════════════════════════════════
|
||||
WIZARD STEPS (melhorado)
|
||||
═══════════════════════════════════════════ */
|
||||
#wizard-steps .step-item {
|
||||
transition: opacity .2s, transform .2s;
|
||||
}
|
||||
#wizard-steps .step-item:not(.done):not(.active) {
|
||||
opacity: .55;
|
||||
}
|
||||
#wizard-steps .step-item.done { color: var(--clr-success); }
|
||||
#wizard-steps .step-item.active { color: var(--clr-primary); font-weight: 700; }
|
||||
|
||||
/* ═══════════════════════════════════════════
|
||||
FORMULÁRIO — campos do Fluig aprimorados
|
||||
═══════════════════════════════════════════ */
|
||||
.has-error .form-control { border-color: var(--clr-danger) !important; }
|
||||
.errorValidate { border-color: var(--clr-danger) !important; }
|
||||
|
||||
.form-control:focus {
|
||||
border-color: var(--clr-primary) !important;
|
||||
box-shadow: 0 0 0 2px rgba(4,80,107,.15) !important;
|
||||
}
|
||||
|
||||
/* ═══════════════════════════════════════════
|
||||
MODAL DE PRODUTOS — aprimorado
|
||||
═══════════════════════════════════════════ */
|
||||
#listaProdutos .table th { font-size: 11px; text-transform: uppercase; }
|
||||
#listaProdutos .table td { font-size: 13px; }
|
||||
#listaProdutos .btn-success { min-width: 80px; }
|
||||
|
||||
/* ═══════════════════════════════════════════
|
||||
RESPONSIVIDADE
|
||||
═══════════════════════════════════════════ */
|
||||
@media (max-width: 768px) {
|
||||
.sc-primary-grid,
|
||||
.sc-secondary-grid { grid-template-columns: 1fr 1fr !important; }
|
||||
|
||||
.table-compras th,
|
||||
.table-compras td { padding: 6px 8px; font-size: 12px; }
|
||||
}
|
||||
@media (max-width: 480px) {
|
||||
.sc-primary-grid,
|
||||
.sc-secondary-grid { grid-template-columns: 1fr !important; }
|
||||
}
|
||||
@@ -44,42 +44,73 @@ function recalcTotal() {
|
||||
|
||||
}
|
||||
|
||||
/* Parse "fieldName___index" IDs used by Fluig Zoom child items */
|
||||
function parseZoomItemId(rawId) {
|
||||
const sep = (rawId || "").indexOf("___");
|
||||
if (sep >= 0) {
|
||||
return { inputId: rawId.substring(0, sep), indice: rawId.substring(sep + 3) };
|
||||
}
|
||||
return { inputId: rawId || "", indice: "" };
|
||||
}
|
||||
|
||||
function setSelectedZoomItem(selectedItem) {
|
||||
if (selectedItem.inputId === "estabelecimento") {
|
||||
// dsFiliais: guarda dados da filial e define gestor da próxima atividade
|
||||
var codigoProtheus = String(selectedItem.PROTHEUS || selectedItem.protheus || "").trim();
|
||||
const { inputId, indice } = parseZoomItemId(selectedItem.inputId);
|
||||
|
||||
if (inputId === "estabelecimento") {
|
||||
const codigoProtheus = String(selectedItem.PROTHEUS || selectedItem.protheus || "").trim();
|
||||
const gestorLoja = String(selectedItem.COLLEAGUE_ID || selectedItem.LOGIN_LOJA || "").trim();
|
||||
|
||||
$("#filialdest").val(selectedItem.LOJA || "");
|
||||
$("#filialest").val(selectedItem.UF || "");
|
||||
$("#filialprotheus").val(codigoProtheus);
|
||||
$("#centro_custo").val(selectedItem.RESPONSAVEL_LOJA || selectedItem.LOJA || "");
|
||||
$("#codigocentroCusto").val(codigoProtheus);
|
||||
|
||||
var gestorLoja = (selectedItem.COLLEAGUE_ID || selectedItem.LOGIN_LOJA || "").trim();
|
||||
$("#gestor_cc").val(gestorLoja);
|
||||
|
||||
if (!codigoProtheus) {
|
||||
console.warn("Filial selecionada sem campo PROTHEUS no dsFiliais.");
|
||||
console.warn("[ZoomHandler] Filial sem PROTHEUS:", selectedItem);
|
||||
}
|
||||
}
|
||||
|
||||
if (inputId === "centroCusto") {
|
||||
$("#gestorNome").val(selectedItem.gestorCentroCusto || "");
|
||||
$("#gestorEmail").val(selectedItem.emailGestor || "");
|
||||
$("#gestor_cc").val(selectedItem.idGestor || "");
|
||||
}
|
||||
|
||||
}
|
||||
if (inputId === "userSolicitante") {
|
||||
$("#emailSolicitante").val(selectedItem.mail || "");
|
||||
}
|
||||
|
||||
function removedZoomItem(removedItem) {
|
||||
if (removedItem.inputId === "estabelecimento") {
|
||||
// Quando remover a filial, limpa os campos relacionados
|
||||
$("#filialdest").val("");
|
||||
$("#filialest").val("");
|
||||
$("#filialprotheus").val("");
|
||||
$("#centro_custo").val("");
|
||||
$("#codigocentroCusto").val("");
|
||||
$("#gestor_cc").val("");
|
||||
if (inputId === "descricao") {
|
||||
$("#codigoItem___" + indice).val(selectedItem.descricao || "");
|
||||
}
|
||||
}
|
||||
|
||||
/* ========= Config ========= */
|
||||
const DATASET_PRODUTOS = "dsComprasProdutos"; // dataset de produtos
|
||||
function removedZoomItem(removedItem) {
|
||||
const { inputId, indice } = parseZoomItemId(removedItem.inputId);
|
||||
|
||||
if (inputId === "estabelecimento") {
|
||||
$("#filialdest, #filialest, #filialprotheus, #centro_custo, #codigocentroCusto, #gestor_cc").val("");
|
||||
}
|
||||
|
||||
if (inputId === "centroCusto") {
|
||||
$("#gestorNome, #gestorEmail, #gestor_cc").val("");
|
||||
}
|
||||
|
||||
if (inputId === "userSolicitante") {
|
||||
$("#emailSolicitante").val("");
|
||||
}
|
||||
|
||||
if (inputId === "descricao") {
|
||||
$("#codigoItem___" + indice + ", #quantidadeItem___" + indice).val("");
|
||||
}
|
||||
}
|
||||
|
||||
/* ========= Config (centralizada em compras_config.js) ========= */
|
||||
const DATASET_PRODUTOS = (typeof ComprasConfig !== "undefined")
|
||||
? ComprasConfig.datasets.produtos
|
||||
: "dsComprasProdutos";
|
||||
let todosProdutos = [];
|
||||
let paginaAtual = 1;
|
||||
const itensPorPagina = 10;
|
||||
@@ -266,9 +297,9 @@ function toggleBotaoAddItem() {
|
||||
}
|
||||
/* ========= Adicionar Item ========= */
|
||||
function adicionarItem() {
|
||||
const cod = $('#produtoCod').val();
|
||||
const cod = $('#produtoCod').val();
|
||||
const desc = $('#descProduto').val();
|
||||
const qtd = $('#quantidade').val();
|
||||
const qtd = $('#quantidade').val() || '1';
|
||||
|
||||
if (!cod) {
|
||||
FLUIGC.toast({ title: 'Atenção', message: 'Selecione um produto/serviço', type: 'warning' });
|
||||
@@ -277,20 +308,17 @@ function adicionarItem() {
|
||||
|
||||
const idx = wdkAddChild('tbItens');
|
||||
|
||||
setTimeout(() => {
|
||||
setTimeout(function () {
|
||||
$('input[name="Codproduto___' + idx + '"]').val(cod);
|
||||
|
||||
const somenteDesc = desc.includes('-') ? desc.split('-').slice(1).join('-').trim() : desc;
|
||||
const somenteDesc = desc.indexOf('-') >= 0 ? desc.split('-').slice(1).join('-').trim() : desc;
|
||||
$('input[name="produtoDesc___' + idx + '"]').val(somenteDesc);
|
||||
$('input[name="qtd___' + idx + '"]').val(qtd).on('input', function () { recalcLinha(this); });
|
||||
$('input[name="ultimoPreco___' + idx + '"]').val(prec).on('input', function () { recalcLinha(this); });
|
||||
$('input[name="qtd___' + idx + '"]').val(qtd);
|
||||
|
||||
atualizarIndex();
|
||||
atualizarTotais();
|
||||
}, 0);
|
||||
|
||||
FLUIGC.toast({ title: 'Item', message: 'Adicionado à lista', type: 'success' });
|
||||
|
||||
limparCamposPrincipais();
|
||||
}
|
||||
|
||||
@@ -380,16 +408,16 @@ $(function () {
|
||||
var step = steps[index];
|
||||
if (!step) return;
|
||||
|
||||
// 👉 se já estava ativo, mostra tudo de novo
|
||||
// se já estava ativo, mostra tudo de novo
|
||||
if ($(this).hasClass("active") && $(".activity:visible").length === 1) {
|
||||
$(".activity").show();
|
||||
$(".activity").css("display", "block");
|
||||
$("#wizard-steps .step-item").removeClass("active");
|
||||
return;
|
||||
}
|
||||
|
||||
// senão, mostra só a activity clicada
|
||||
$(".activity").hide();
|
||||
$(".activity-" + step.state).show();
|
||||
$(".activity").css("display", "none");
|
||||
$(".activity-" + step.state).css("display", "block");
|
||||
|
||||
$("#wizard-steps .step-item").removeClass("active");
|
||||
$(this).addClass("active");
|
||||
@@ -408,30 +436,32 @@ function setLabel(id, valor) {
|
||||
|
||||
function badgeClassByStatus(status) {
|
||||
var s = String(status || "").toLowerCase();
|
||||
if (!s) return "badge bg-secondary";
|
||||
if (s.indexOf("erro") >= 0 || s.indexOf("reprov") >= 0 || s.indexOf("cancel") >= 0) return "badge bg-danger";
|
||||
if (s.indexOf("aguard") >= 0 || s.indexOf("pend") >= 0) return "badge bg-warning";
|
||||
if (s.indexOf("sucesso") >= 0 || s.indexOf("aprov") >= 0 || s.indexOf("gerad") >= 0 || s.indexOf("liberad") >= 0) return "badge bg-success";
|
||||
if (s.indexOf("bloque") >= 0 || s.indexOf("rejeit") >= 0) return "badge bg-danger";
|
||||
return "badge bg-info";
|
||||
if (!s || s === "sem cotacao" || s === "sem pedido" || s === "-") return "badge-status badge-waiting";
|
||||
if (s.indexOf("erro") >= 0 || s.indexOf("reprov") >= 0 || s.indexOf("cancel") >= 0) return "badge-status badge-rejected";
|
||||
if (s.indexOf("bloque") >= 0 || s.indexOf("rejeit") >= 0) return "badge-status badge-blocked";
|
||||
if (s.indexOf("aguard") >= 0 || s.indexOf("pend") >= 0) return "badge-status badge-pending";
|
||||
if (s.indexOf("sucesso") >= 0 || s.indexOf("aprov") >= 0 || s.indexOf("gerad") >= 0 || s.indexOf("liberad") >= 0 || s.indexOf("conclui") >= 0) return "badge-status badge-approved";
|
||||
return "badge-status badge-processing";
|
||||
}
|
||||
|
||||
var BADGE_VARIANTS = "badge-waiting badge-pending badge-approved badge-rejected badge-blocked badge-processing";
|
||||
|
||||
function setBadge(selector, valor) {
|
||||
var texto = String(valor || "").trim() || "-";
|
||||
var classe = badgeClassByStatus(texto);
|
||||
var textoLower = texto.toLowerCase();
|
||||
var classe = badgeClassByStatus(texto);
|
||||
|
||||
// Mantem os badges de resumo da SC sem destaque verde para sucesso/geracao.
|
||||
// Mantém badges de resumo da SC como "em andamento" para não inflar expectativa visual.
|
||||
if (
|
||||
(selector === "#statusSCProtheus_label" && textoLower.indexOf("sc cadastrada com sucesso") >= 0) ||
|
||||
(selector === "#statusSC_label" && textoLower.indexOf("pedido gerado") >= 0)
|
||||
) {
|
||||
classe = "badge bg-info";
|
||||
classe = "badge-status badge-processing";
|
||||
}
|
||||
|
||||
$(selector)
|
||||
.text(texto)
|
||||
.removeClass("bg-secondary bg-success bg-danger bg-warning bg-info")
|
||||
.removeClass(BADGE_VARIANTS)
|
||||
.addClass(classe);
|
||||
}
|
||||
|
||||
@@ -734,7 +764,7 @@ function renderizarResultadoCotacao(resumo) {
|
||||
var statusApiTxt = escapeHTML(linha.statusApi || "-");
|
||||
var statusRaw = String(linha.label || "").trim();
|
||||
var statusTxt = escapeHTML(statusRaw);
|
||||
var badgeStatus = linha.badge || "badge bg-secondary";
|
||||
var badgeStatus = linha.badge || "badge-status badge-waiting";
|
||||
var classeCard = classeCardCotacao(linha.tipo);
|
||||
var qtdTxt = escapeHTML(String(linha.quantidade || "-"));
|
||||
var entregaTxt = escapeHTML(normalizarDataProtheus(linha.dataPrevista || ""));
|
||||
@@ -1303,3 +1333,66 @@ function beforeSendValidate(numState, nextState) {
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
/* ── Accordion de histórico de atividades ─────────────────────────
|
||||
Chamada pelo script.js após cada showAndBlock() para colapsar
|
||||
as seções de atividades já concluídas.
|
||||
----------------------------------------------------------------- */
|
||||
var ACTIVITY_META = {
|
||||
"0": { titulo: "Dados da Solicitação", campos: ["usuarioSolicitante", "estabelecimento", "tipoSolicitacao"] },
|
||||
"1": { titulo: "Dados da Solicitação", campos: ["usuarioSolicitante", "estabelecimento"] },
|
||||
"4": { titulo: "Análise do Gestor", campos: ["userValidacaoGestor", "dataValidacaoGestor"] },
|
||||
"6": { titulo: "Validação Compras", campos: ["userValidacaoCompras", "dataValidacaoCompras"] },
|
||||
"24": { titulo: "Problema na Compra", campos: [] },
|
||||
"31": { titulo: "Realização da Compra", campos: ["userRealizacaoCompras", "dataRealizacaoCompras"] },
|
||||
"57": { titulo: "Aprovação p/ Cotação", campos: ["userCotacaoGestor", "dataAprovCompras"] },
|
||||
"114": { titulo: "SC no Protheus", campos: [] },
|
||||
"121": { titulo: "Validação da Diretoria", campos: ["user_validacao_gestor", "data_validacao_gestor"] }
|
||||
};
|
||||
|
||||
function _lerCampoResumo(id) {
|
||||
var $el = $("#" + id);
|
||||
if (!$el.length) return "";
|
||||
var val = $el.is("span, div") ? $el.text().trim() : String($el.val() || "").trim();
|
||||
return (val && val !== "-") ? val : "";
|
||||
}
|
||||
|
||||
function colapsarAtividadesAnteriores(numeros) {
|
||||
for (var i = 0; i < numeros.length; i++) {
|
||||
var num = numeros[i];
|
||||
var $secao = $(".activity-" + num);
|
||||
if (!$secao.length || $secao.hasClass("accordion-pronto")) continue;
|
||||
|
||||
var meta = ACTIVITY_META[String(num)] || { titulo: "Etapa " + num, campos: [] };
|
||||
|
||||
// Envolve o conteúdo inteiro num .activity-body colapsável
|
||||
$secao.children().wrapAll('<div class="activity-body"></div>');
|
||||
|
||||
// Monta texto de resumo a partir dos campos da etapa já preenchida
|
||||
var partes = [];
|
||||
for (var c = 0; c < meta.campos.length && partes.length < 2; c++) {
|
||||
var val = _lerCampoResumo(meta.campos[c]);
|
||||
if (val) partes.push(escapeHTML(val));
|
||||
}
|
||||
var resumo = partes.length ? partes.join(" · ") : "Concluído";
|
||||
|
||||
// Injeta cabeçalho clicável antes do body
|
||||
$secao.prepend(
|
||||
'<div class="activity-header">' +
|
||||
'<span class="activity-header-check">✓</span>' +
|
||||
'<span class="activity-header-titulo">' + escapeHTML(meta.titulo) + '</span>' +
|
||||
'<span class="activity-header-resumo">' + resumo + '</span>' +
|
||||
'<span class="activity-header-caret">▼</span>' +
|
||||
'</div>'
|
||||
);
|
||||
|
||||
$secao.addClass("accordion-pronto is-collapsed");
|
||||
|
||||
// Fecha sobre si mesmo para manter contexto correto no closure
|
||||
(function ($s) {
|
||||
$s.on("click.accordion", ".activity-header", function () {
|
||||
$s.toggleClass("is-collapsed");
|
||||
});
|
||||
}($secao));
|
||||
}
|
||||
}
|
||||
|
||||
@@ -2,86 +2,38 @@ $(document).ready(function () {
|
||||
if ($("#formMode").val() == "VIEW") {
|
||||
showAndBlock(["all"]);
|
||||
} else {
|
||||
//show the right fields
|
||||
var activity = $("#activity").val();
|
||||
var requestDate = getCurrentDate();
|
||||
|
||||
$(".activity").hide();
|
||||
// Ponto de partida: tudo visível, depois escondemos só o que ainda não chegou
|
||||
$(".activity").css("display", "block");
|
||||
|
||||
$(".activity-" + activity).show();
|
||||
|
||||
if (activity == 0 || activity == 1) {
|
||||
//primeira atividade
|
||||
//$("#dataAbertura").val(requestDate[0] + " - " + requestDate[1]);
|
||||
if (activity == 0 || activity == 1 || !activity) {
|
||||
// Atividade inicial — esconde tudo que ainda não foi liberado
|
||||
$(".activity-121, .activity-18, .activity-24").css("display", "none");
|
||||
$("#dataAbertura").val(requestDate[0]);
|
||||
add_new_row("tabelaItens");
|
||||
} else if (activity == 4) {
|
||||
showAndBlock([0]);
|
||||
$("#userValidacaoGestor").val($("#currentUserName").val());
|
||||
$("#dataValidacaoGestor").val(
|
||||
requestDate[0] + " - " + requestDate[1]
|
||||
);
|
||||
updt_line();
|
||||
} else if (activity == 6) {
|
||||
showAndBlock([0, 4]);
|
||||
$("#userValidacaoCompras").val($("#currentUserName").val());
|
||||
$("#dataValidacaoCompras").val(
|
||||
requestDate[0] + " - " + requestDate[1]
|
||||
);
|
||||
|
||||
if ($("#justificativaDecisaoGestor").val() == "") {
|
||||
$(".justificativa-activity-4").hide();
|
||||
}
|
||||
updt_line();
|
||||
|
||||
} else if (activity == 57) {
|
||||
$("#userCotacaoGestor").val($("#currentUserName").val());
|
||||
$("#dataAprovCompras").val(
|
||||
requestDate[0] + " - " + requestDate[1]
|
||||
);
|
||||
showAndBlock([0, 4, 6]);
|
||||
|
||||
if ($("#justificativaDecisaoGestor").val() == "") {
|
||||
$(".justificativa-activity-4").hide();
|
||||
}
|
||||
if ($("#justificativaDecisaoCompras").val() == "") {
|
||||
$(".justificativa-activity-6").hide();
|
||||
} else if (activity == 121) {
|
||||
// Gestor analisa — esconde atividades futuras
|
||||
$(".activity-18, .activity-24").css("display", "none");
|
||||
showAndBlock([1]);
|
||||
if (typeof colapsarAtividadesAnteriores === "function") {
|
||||
colapsarAtividadesAnteriores([1]);
|
||||
}
|
||||
$("#user_validacao_gestor").val($("#currentUserName").val());
|
||||
$("#data_validacao_gestor").val(requestDate[0] + " - " + requestDate[1]);
|
||||
updt_line();
|
||||
|
||||
} else if (activity == 31) {
|
||||
$("#userRealizacaoCompras").val($("#currentUserName").val());
|
||||
$("#dataRealizacaoCompras").val(
|
||||
requestDate[0] + " - " + requestDate[1]
|
||||
);
|
||||
showAndBlock([0, 4, 6, 57]);
|
||||
|
||||
if ($("#justificativaDecisaoGestor").val() == "") {
|
||||
$(".justificativa-activity-4").hide();
|
||||
}
|
||||
if ($("#justificativaDecisaoCompras").val() == "") {
|
||||
$(".justificativa-activity-6").hide();
|
||||
}
|
||||
updt_line();
|
||||
} else if (activity == 18) {
|
||||
if ($("justificativaValidaProblema") != "") {
|
||||
showAndBlock([0, 4, 6, 24, 57, 31]);
|
||||
} else {
|
||||
showAndBlock([0, 4, 6, 31]);
|
||||
// Validação dos itens — esconde só a atividade futura
|
||||
$(".activity-24").css("display", "none");
|
||||
showAndBlock([1, 121]);
|
||||
if (typeof colapsarAtividadesAnteriores === "function") {
|
||||
colapsarAtividadesAnteriores([1, 121]);
|
||||
}
|
||||
$("#userValidacaoItens").val($("#currentUserName").val());
|
||||
$("#dataValidacaoItens").val(requestDate[0] + " - " + requestDate[1]);
|
||||
|
||||
if ($("#justificativaDecisaoGestor").val() == "") {
|
||||
$(".justificativa-activity-4").hide();
|
||||
}
|
||||
if ($("#justificativaDecisaoCompras").val() == "") {
|
||||
$(".justificativa-activity-6").hide();
|
||||
}
|
||||
if ($("#consideracoesCompras").val() == "") {
|
||||
$(".justificativa-activity-31").hide();
|
||||
}
|
||||
|
||||
$("input[name=validacaoItens]").on("change", function () {
|
||||
$(".justificativaDecisaoItens").hide();
|
||||
if (
|
||||
@@ -92,19 +44,13 @@ $(document).ready(function () {
|
||||
}
|
||||
});
|
||||
$("input[name=validacaoItens]").trigger("change");
|
||||
|
||||
updt_line();
|
||||
} else if (activity == 24) {
|
||||
showAndBlock([0, 4, 6, 31, 18]);
|
||||
|
||||
if ($("#justificativaDecisaoGestor").val() == "") {
|
||||
$(".justificativa-activity-4").hide();
|
||||
}
|
||||
if ($("#justificativaDecisaoCompras").val() == "") {
|
||||
$(".justificativa-activity-6").hide();
|
||||
}
|
||||
if ($("#consideracoesCompras").val() == "") {
|
||||
$(".justificativa-activity-31").hide();
|
||||
} else if (activity == 24) {
|
||||
// Última atividade — tudo visível, bloqueia anteriores
|
||||
showAndBlock([1, 121, 18]);
|
||||
if (typeof colapsarAtividadesAnteriores === "function") {
|
||||
colapsarAtividadesAnteriores([1, 121, 18]);
|
||||
}
|
||||
updt_line();
|
||||
}
|
||||
@@ -143,7 +89,7 @@ function formatarMoedasTabela(ids) {
|
||||
//show the activity and then block the fields
|
||||
function showAndBlock(activity) {
|
||||
for (var i = 0, l = activity.length; i < l; i++) {
|
||||
$(".activity-" + activity[i]).show();
|
||||
$(".activity-" + activity[i]).css("display", "block");
|
||||
$(".hideButton").hide();
|
||||
$(".activity-" + activity[i] + " :input").each(function () {
|
||||
$(this).attr("readonly", "readonly");
|
||||
@@ -267,99 +213,13 @@ var beforeSendValidate = function (numState, nextState) {
|
||||
}
|
||||
};
|
||||
|
||||
function setSelectedZoomItem(selectedItem) {
|
||||
var name_item = selectedItem.inputId;
|
||||
var ehItem = name_item.indexOf("___") >= 0;
|
||||
var indice = "";
|
||||
if (ehItem){
|
||||
var valores = name_item.split("___");
|
||||
name_item = valores[0];
|
||||
indice = valores[1];
|
||||
}
|
||||
|
||||
var dtsCentroCusto = DatasetFactory.getDataset(
|
||||
"ds_centroCusto",
|
||||
null,
|
||||
null,
|
||||
null
|
||||
).values;
|
||||
|
||||
var nomeGestorComercial = dtsCentroCusto[0].gestorCentroCusto;
|
||||
var emailGestorComercial = dtsCentroCusto[0].emailGestor;
|
||||
var idGestorComercial = dtsCentroCusto[0].idGestor;
|
||||
|
||||
var nomeGestorOperacoes = dtsCentroCusto[2].gestorCentroCusto;
|
||||
var emailGestorOperacoes = dtsCentroCusto[2].emailGestor;
|
||||
var idGestorOperacoes = dtsCentroCusto[2].idGestor;
|
||||
|
||||
if (name_item == "estabelecimento") {
|
||||
let estabelecimento = selectedItem["estabelecimento"];
|
||||
let cnpj = selectedItem["CNPJ"];
|
||||
let protheus = selectedItem["CODIGO"]
|
||||
$("#cnpj").val(cnpj);
|
||||
$("#protheus").val(protheus);
|
||||
|
||||
|
||||
|
||||
if (estabelecimento.includes("MATRIZ")) {
|
||||
} else if (estabelecimento.includes("CD")) {
|
||||
window["centroCusto"].setValue("Operações");
|
||||
$("#gestorNome").val(nomeGestorOperacoes);
|
||||
$("#gestorEmail").val(emailGestorOperacoes);
|
||||
$("#gestor_cc").val(idGestorOperacoes);
|
||||
} else {
|
||||
window["centroCusto"].setValue("Comercial");
|
||||
$("#gestorNome").val(nomeGestorComercial);
|
||||
$("#gestorEmail").val(emailGestorComercial);
|
||||
$("#gestor_cc").val(idGestorComercial);
|
||||
}
|
||||
}
|
||||
|
||||
if (name_item == "centroCusto") {
|
||||
$("#gestorNome").val(selectedItem["gestorCentroCusto"]);
|
||||
$("#gestorEmail").val(selectedItem["emailGestor"]);
|
||||
$("#gestor_cc").val(selectedItem["idGestor"]);
|
||||
}
|
||||
|
||||
if (name_item == "userSolicitante") {
|
||||
$("#emailSolicitante").val(selectedItem.mail);
|
||||
}
|
||||
|
||||
if (name_item == "descricao") {
|
||||
$("#codigoItem" + "___" + indice).val(selectedItem["descricao"]);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
function removedZoomItem(removedItem) {
|
||||
var name_item = removedItem.inputId;
|
||||
var ehItem = name_item.indexOf("___") >= 0;
|
||||
var indice = "";
|
||||
if (ehItem){
|
||||
var valores = name_item.split("___");
|
||||
name_item = valores[0];
|
||||
indice = valores[1];
|
||||
}
|
||||
|
||||
if (name_item == "userSolicitante") {
|
||||
$("#emailSolicitante").val("");
|
||||
} else if (name_item == "centroCusto") {
|
||||
$("#gestorNome").val("");
|
||||
$("#gestorEmail").val("");
|
||||
$("#gestor_cc").val("");
|
||||
} else if (~name_item.indexOf("___")) {
|
||||
var linha = name_item.split("___");
|
||||
|
||||
if (linha[0] == "descricao") {
|
||||
$("#codigoItem___" + linha[1]).val("");
|
||||
$("#quantidadeItem___" + linha[1]).val("");
|
||||
}
|
||||
}
|
||||
|
||||
if (name_item == "descricao") {
|
||||
$("#codigoItem" + "___" + indice).val("");
|
||||
}
|
||||
}
|
||||
// setSelectedZoomItem e removedZoomItem foram consolidados em compras_digital.js
|
||||
// (carregado via <script> no HTML, sempre sobrescreve esta versão)
|
||||
// Mantido aqui apenas como referência histórica — NÃO REMOVER o bloco de comentário.
|
||||
/*
|
||||
function setSelectedZoomItem(selectedItem) { ... }
|
||||
function removedZoomItem(removedItem) { ... }
|
||||
*/
|
||||
|
||||
function add_new_row(table) {
|
||||
var row = wdkAddChild(table);
|
||||
|
||||
Reference in New Issue
Block a user