This commit is contained in:
Andrey Cunha 2026-05-11 21:54:49 -03:00
parent ba5d7dae57
commit a71f963e37
17 changed files with 3091 additions and 4186 deletions

File diff suppressed because one or more lines are too long

View File

@ -11,3 +11,4 @@
2026-05-06 20:20:13,505 [Worker-4: Loading available Gradle versions] INFO o.e.b.c.i.u.g.PublishedGradleVersions - Gradle version information cache is up-to-date. Trying to read.
2026-05-06 20:21:56,730 [Worker-6: Loading available Gradle versions] INFO o.e.b.c.i.u.g.PublishedGradleVersions - Gradle version information cache is up-to-date. Trying to read.
2026-05-11 14:40:40,614 [Worker-6: Loading available Gradle versions] INFO o.e.b.c.i.u.g.PublishedGradleVersions - Gradle version information cache is out-of-date. Trying to update.
2026-05-11 21:22:28,359 [Worker-2: Loading available Gradle versions] INFO o.e.b.c.i.u.g.PublishedGradleVersions - Gradle version information cache is up-to-date. Trying to read.

View File

@ -0,0 +1,7 @@
{
"permissions": {
"allow": [
"PowerShell(Get-ChildItem -Path \"c:\\\\Python\\\\Fluig Ginseng\\\\fluig\\\\checklist\\\\fluig\\\\compras_digital\" -Recurse -Force | Select-Object FullName, @{Name='Type';Expression={if\\($_.PSIsContainer\\){'DIR'}else{'FILE'}}} | Sort-Object FullName | Format-Table -AutoSize)"
]
}
}

View File

@ -64,28 +64,23 @@ function createDataset(fields, constraints, sortFields) {
return dataset;
}
// Criação das colunas
function criarEstrutura(dataset) {
dataset.addColumn("STATUS", DatasetFieldType.STRING);
dataset.addColumn("RETORNO", DatasetFieldType.STRING);
dataset.addColumn("STATUS");
dataset.addColumn("RETORNO");
}
// Função para buscar parâmetro nas constraints
function getParametro(constraints, campo) {
var valor = "";
if (constraints && constraints.length > 0) {
for each (var c in constraints) {
if (c.getFieldName().trim().toUpperCase() === campo.trim().toUpperCase()) {
valor = c.getInitialValue();
break;
}
if (!constraints) return "";
var campoUpper = String(campo || "").trim().toUpperCase();
for (var i = 0; i < constraints.length; i++) {
var c = constraints[i];
if (String(c.fieldName || "").trim().toUpperCase() === campoUpper) {
return String(c.initialValue || "");
}
}
return valor;
return "";
}
// Trim com segurança
function trim(valor) {
if (!valor) return "";
return valor.trim();
return String(valor == null ? "" : valor).trim();
}

View File

@ -18,7 +18,7 @@ function createDataset(fields, constraints, sortFields) {
try {
var clientService = fluigAPI.getAuthorizeClientService();
var data = {
companyId: "1",
companyId: String(getValue("WKCompany") || "1"),
serviceCode: "Postprod",
endpoint: "/uf_mata010/",
method: "get",

View File

@ -4,13 +4,13 @@ function createDataset(fields, constraints, sortFields) {
dataset.addColumn("mensagem");
dataset.addColumn("erro");
log.info("### Enviando dados para Protheus com autenticação ###");
log.info("### Enviando dados para Protheus via fluigAPI ###");
try {
var jsonData = "{}";
if (constraints) {
for (var i = 0; i < constraints.length; i++) {
if (constraints[i].fieldName == "params" && constraints[i].initialValue) {
if (constraints[i].fieldName === "params" && constraints[i].initialValue) {
jsonData = constraints[i].initialValue;
break;
}
@ -18,54 +18,25 @@ function createDataset(fields, constraints, sortFields) {
}
log.info("Dados recebidos: " + jsonData);
var url = "https://rest.grupoginseng.com.br/rest/uf_mata010";
var urlObj = new java.net.URL(url);
var httpConn = urlObj.openConnection();
var clientService = fluigAPI.getAuthorizeClientService();
var data = {
companyId: String(getValue("WKCompany") || "1"),
serviceCode: "Postprod",
endpoint: "/rest/uf_mata010",
method: "post",
timeoutService: "60000",
params: JSON.parse(jsonData),
headers: { "Content-Type": "application/json" }
};
var usuario = "fluig";
var senha = "Ginseng@";
var authString = usuario + ":" + senha;
var authBytes = new java.lang.String(authString).getBytes("UTF-8");
var encodedAuth = java.util.Base64.getEncoder().encodeToString(authBytes);
var vo = clientService.invoke(JSON.stringify(data));
var response = vo ? String(vo.getResult() || "") : "";
httpConn.setDoOutput(true);
httpConn.setRequestMethod("POST");
httpConn.setRequestProperty("Content-Type", "application/json");
httpConn.setRequestProperty("Accept", "application/json");
httpConn.setRequestProperty("Authorization", "Basic " + encodedAuth);
httpConn.setConnectTimeout(30000);
httpConn.setReadTimeout(30000);
var outputStream = httpConn.getOutputStream();
var writer = new java.io.OutputStreamWriter(outputStream, "UTF-8");
writer.write(jsonData);
writer.flush();
writer.close();
outputStream.close();
// Ler resposta ou erro
var response = "";
try {
var inputStream = httpConn.getInputStream();
var scanner = new java.util.Scanner(inputStream, "UTF-8");
response = scanner.useDelimiter("\\A").hasNext() ? scanner.next() : "";
scanner.close();
} catch (e) {
var errorStream = httpConn.getErrorStream();
if (errorStream != null) {
var scanner = new java.util.Scanner(errorStream, "UTF-8");
response = scanner.useDelimiter("\\A").hasNext() ? scanner.next() : "";
scanner.close();
}
}
log.info("Response bruto: " + response);
// Adiciona no dataset sempre, sem depender do status HTTP
log.info("Response: " + response);
dataset.addRow(["OK", response, ""]);
} catch (error) {
log.error("Erro completo: " + error.toString());
log.error("Erro: " + error.toString());
dataset.addRow(["Erro", "", error.toString()]);
}

View File

@ -5,60 +5,57 @@ function onSync(lastSyncDate) {}
function createDataset(fields, constraints, sortFields) {
var dataset = DatasetBuilder.newDataset();
// Definir as colunas
dataset.addColumn("codigoCentroCusto");
dataset.addColumn("centroCusto");
dataset.addColumn("gestorCentroCusto");
dataset.addColumn("idGestor");
dataset.addColumn("emailGestor");
dataset.addColumn("diretorCentroCusto");
dataset.addColumn("idDiretor");
dataset.addColumn("diretorGeral");
dataset.addColumn("idDiretorGeral");
// Lista dos centros de custo
var dados = [
// Comercial dividido por estado
["41101", "Comercial Alagoas", "Raquel Tenorio ", "Analanny Magalhães", "João Marcelo"],
["41101", "Comercial Bahia", "Arianne Sodre", "Analanny Magalhães", "João Marcelo"],
["41101", "Comercial Sergipe", "Iolanda Bezerra", "Analanny Magalhães", "João Marcelo"],
["41101", "Marketing e Treinamento", "Andreia Leite", "João Marcelo", "João Marcelo"],
// Outros centros de custo (exemplo que você já tinha)
["51101", "Diretoria e Gestão", "João Marcelo", "Diogo Demetrio", "João Marcelo"],
["51102", "Operações", "Diogo Demetrio", "Ariklenyo Nascimento", "João Marcelo"],
["51103", "Controladoria", "Ariklenyo Nascimento", "Marla Palma", "João Marcelo"],
["51104", "Compliance", "Marla Palma", "Lucila Brandão", "João Marcelo"],
["51107", "Administrativo", "Lucila Brandão", "Francine Peiter", "João Marcelo"],
["51110", "Gente e Cultura", "Francine Peiter", "Igor Oliveira", "João Marcelo"],
["51113", "TI", "Igor Oliveira", "Lucas Rocha", "João Marcelo"],
["51114", "Projetos e Performance", "Lucas Rocha", "Andrey Cunha", "João Marcelo"],
["teste", "teste", "Andrey Cunha", "Andrey Cunha", "João Marcelo"]
{ cod: "41101", cc: "Comercial Alagoas", gestor: "Raquel Tenorio", diretor: "Analanny Magalhães", dg: "João Marcelo" },
{ cod: "41101", cc: "Comercial Bahia", gestor: "Arianne Sodre", diretor: "Analanny Magalhães", dg: "João Marcelo" },
{ cod: "41101", cc: "Comercial Sergipe", gestor: "Iolanda Bezerra", diretor: "Analanny Magalhães", dg: "João Marcelo" },
{ cod: "41101", cc: "Marketing e Treinamento", gestor: "Andreia Leite", diretor: "João Marcelo", dg: "João Marcelo" },
{ cod: "51101", cc: "Diretoria e Gestão", gestor: "João Marcelo", diretor: "Diogo Demetrio", dg: "João Marcelo" },
{ cod: "51102", cc: "Operações", gestor: "Diogo Demetrio", diretor: "Ariklenyo Nascimento", dg: "João Marcelo" },
{ cod: "51103", cc: "Controladoria", gestor: "Ariklenyo Nascimento", diretor: "Marla Palma", dg: "João Marcelo" },
{ cod: "51104", cc: "Compliance", gestor: "Marla Palma", diretor: "Lucila Brandão", dg: "João Marcelo" },
{ cod: "51107", cc: "Administrativo", gestor: "Lucila Brandão", diretor: "Francine Peiter", dg: "João Marcelo" },
{ cod: "51110", cc: "Gente e Cultura", gestor: "Francine Peiter", diretor: "Igor Oliveira", dg: "João Marcelo" },
{ cod: "51113", cc: "TI", gestor: "Igor Oliveira", diretor: "Lucas Rocha", dg: "João Marcelo" },
{ cod: "51114", cc: "Projetos e Performance", gestor: "Lucas Rocha", diretor: "Andrey Cunha", dg: "João Marcelo" }
];
// Função para buscar matrícula pelo nome
function getMatricula(nome) {
if (!nome) return "";
var c1 = DatasetFactory.createConstraint("colleagueName", nome, nome, ConstraintType.MUST);
var dsUser = DatasetFactory.getDataset("colleague", ["colleagueId"], [c1], null);
return dsUser.rowsCount > 0 ? dsUser.getValue(0, "colleagueId") : "";
function getColleagueById(nome) {
if (!nome) return { id: "", email: "" };
try {
var c1 = DatasetFactory.createConstraint("colleagueName", nome, nome, ConstraintType.MUST);
var ds = DatasetFactory.getDataset("colleague", ["colleagueId", "mail"], [c1], null);
if (ds && ds.rowsCount > 0) {
return {
id: String(ds.getValue(0, "colleagueId") || ""),
email: String(ds.getValue(0, "mail") || "")
};
}
} catch (e) {}
return { id: "", email: "" };
}
// Preenche dataset
for (var i = 0; i < dados.length; i++) {
var idGestor = getMatricula(dados[i][2]);
var idDiretor = getMatricula(dados[i][3]);
var idDiretorGeral = getMatricula(dados[i][4]);
var d = dados[i];
var gestor = getColleagueById(d.gestor);
var diretor = getColleagueById(d.diretor);
var dg = getColleagueById(d.dg);
dataset.addRow([
dados[i][0], // codigoCentroCusto
dados[i][1], // centroCusto
dados[i][2], // gestor
idGestor,
dados[i][3], // diretor
idDiretor,
dados[i][4], // diretor geral
idDiretorGeral
d.cod, d.cc,
d.gestor, gestor.id, gestor.email,
d.diretor, diretor.id,
d.dg, dg.id
]);
}

View File

@ -11,26 +11,19 @@ function createDataset(fields, constraints, sortFields) {
log.info("### Iniciando criação do dataset de Condições de Pagamento ###");
var servicecode = 'API_CONDICAO_PAGAMENTO'; // Nome do serviço cadastrado no Fluig
var usuario = "fluig";
var senha = "Ginseng@";
// Autenticação gerenciada pelo cadastro do serviço no Fluig (sem credenciais no código)
var servicecode = 'API_CONDICAO_PAGAMENTO';
try {
log.info("Iniciando chamada para o clientService...");
var clientService = fluigAPI.getAuthorizeClientService();
var data = {
companyId: "1",
companyId: String(getValue("WKCompany") || "1"),
serviceCode: servicecode,
endpoint: "https://rest.grupoginseng.com.br/rest/api/fat/v1/paymentcondition?Fields=Code,Plots.Description&Page=1&PageSize=100",
method: 'get',
timeoutService: '60000',
params: {},
options: {
encoding: 'UTF-8',
useBasicAuth: true,
username: usuario,
password: senha
}
params: {}
};
log.info("Parâmetros da chamada: " + JSON.stringify(data));

View File

@ -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>

View File

@ -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);
});

View File

@ -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]
}
}
};

View File

@ -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; }
}

View File

@ -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 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">&#9660;</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));
}
}

View File

@ -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);

File diff suppressed because it is too large Load Diff

View File

@ -1,5 +1,5 @@
<?xml version="1.0" encoding="UTF-8"?>
<java version="1.8.0_202" class="java.beans.XMLDecoder">
<java version="1.8.0_481" class="java.beans.XMLDecoder">
<object class="java.util.HashMap">
<void method="put">
<string>volume</string>
@ -151,5 +151,163 @@
</void>
</array>
</void>
<void method="put">
<string>camposFormulario, documentoId = 9305</string>
<array class="java.lang.String" length="51">
<void index="0">
<string>activity</string>
</void>
<void index="1">
<string>centro_custo</string>
</void>
<void index="2">
<string>codigocentroCusto</string>
</void>
<void index="3">
<string>Codproduto</string>
</void>
<void index="4">
<string>cotacaoSCProtheus</string>
</void>
<void index="5">
<string>currentUserId</string>
</void>
<void index="6">
<string>currentUsermail</string>
</void>
<void index="7">
<string>currentUserName</string>
</void>
<void index="8">
<string>dataCadastroSCProtheus</string>
</void>
<void index="9">
<string>dataNec</string>
</void>
<void index="10">
<string>dataValidacaoItens</string>
</void>
<void index="11">
<string>data_validacao_gestor</string>
</void>
<void index="12">
<string>descProduto</string>
</void>
<void index="13">
<string>emailSolicitante</string>
</void>
<void index="14">
<string>emissaoSCProtheus</string>
</void>
<void index="15">
<string>empresa</string>
</void>
<void index="16">
<string>estabelecimento</string>
</void>
<void index="17">
<string>fdComprovante</string>
</void>
<void index="18">
<string>filialdest</string>
</void>
<void index="19">
<string>filialest</string>
</void>
<void index="20">
<string>filialprotheus</string>
</void>
<void index="21">
<string>fnComprovante</string>
</void>
<void index="22">
<string>formMode</string>
</void>
<void index="23">
<string>gestor_cc</string>
</void>
<void index="24">
<string>horaCadastroSCProtheus</string>
</void>
<void index="25">
<string>justificativaDecisaoItens</string>
</void>
<void index="26">
<string>justificativaValidaProblema</string>
</void>
<void index="27">
<string>justi_decisao_gestor</string>
</void>
<void index="28">
<string>moreInfo</string>
</void>
<void index="29">
<string>numeroSCProtheus</string>
</void>
<void index="30">
<string>observacoes</string>
</void>
<void index="31">
<string>pedidoSCProtheus</string>
</void>
<void index="32">
<string>produtoCod</string>
</void>
<void index="33">
<string>produtoDesc</string>
</void>
<void index="34">
<string>produtoLink</string>
</void>
<void index="35">
<string>qtd</string>
</void>
<void index="36">
<string>qtdItensSCProtheus</string>
</void>
<void index="37">
<string>quantidade</string>
</void>
<void index="38">
<string>requesterId</string>
</void>
<void index="39">
<string>requesterMail</string>
</void>
<void index="40">
<string>solicitanteSCProtheus</string>
</void>
<void index="41">
<string>statusAtendimento</string>
</void>
<void index="42">
<string>statusSCProtheus</string>
</void>
<void index="43">
<string>tipoSolicitacao</string>
</void>
<void index="44">
<string>urgencia</string>
</void>
<void index="45">
<string>userValidacaoItens</string>
</void>
<void index="46">
<string>user_validacao_gestor</string>
</void>
<void index="47">
<string>usuarioSolicitante</string>
</void>
<void index="48">
<string>validacaoItens</string>
</void>
<void index="49">
<string>valorTotalCotacao</string>
</void>
<void index="50">
<string>WKNumProces</string>
</void>
</array>
</void>
</object>
</java>