This commit is contained in:
2026-05-06 16:01:10 -03:00
parent f31f809ce7
commit 4a31410351
26 changed files with 22041 additions and 2083 deletions
@@ -58,27 +58,281 @@
margin-bottom: 24px;
}
.change-weight { font-weight: 400 !important; }
.sc-status-panel {
margin-top: 15px;
padding: 18px;
border: 1px solid #d8e1e8;
border-radius: 12px;
background: #f7fafc;
box-shadow: 0 2px 10px rgba(12, 50, 74, 0.08);
}
.sc-primary-grid,
.sc-secondary-grid {
display: grid;
grid-template-columns: repeat(3, minmax(220px, 1fr));
gap: 12px;
}
.sc-primary-grid {
margin-bottom: 12px;
}
.sc-secondary-grid {
gap: 8px 12px;
}
.sc-info {
background: #fff;
border-radius: 10px;
padding: 12px 14px;
min-height: 72px;
}
.sc-info--primary {
border-left: 4px solid #04506b;
box-shadow: inset 0 0 0 1px #d9e4ec;
}
.sc-info--secondary {
box-shadow: inset 0 0 0 1px #e3ebf2;
opacity: .96;
}
.sc-info--clickable {
cursor: pointer;
transition: box-shadow .2s ease, transform .2s ease;
}
.sc-info--clickable:hover {
transform: translateY(-1px);
box-shadow: inset 0 0 0 1px #c8d9e7, 0 4px 12px rgba(8, 47, 72, 0.1);
}
.sc-label {
font-size: 11px;
color: #4d6073;
letter-spacing: .04em;
text-transform: uppercase;
margin-bottom: 4px;
}
.sc-value {
font-size: 15px;
font-weight: 600;
color: #24313f;
word-break: break-word;
}
.sc-info--primary .sc-value {
font-size: 30px;
line-height: 1.1;
color: #102a43;
font-weight: 700;
letter-spacing: .01em;
}
.sc-hint {
display: block;
margin-top: 6px;
font-size: 11px;
color: #5f7386;
letter-spacing: .02em;
}
.sc-value.badge {
display: inline-flex;
align-items: center;
min-height: 30px;
padding: 6px 12px;
border-radius: 999px;
font-size: 12px;
font-weight: 700;
line-height: 1;
}
.sc-timeline-wrap {
margin-top: 16px;
padding-top: 0;
border-top: 1px solid transparent;
transition: background-color .25s ease, max-height .25s ease, opacity .25s ease, padding-top .25s ease;
max-height: 0;
opacity: 0;
overflow: hidden;
pointer-events: none;
}
.sc-timeline-wrap.is-open {
padding-top: 14px;
border-top-color: #d7e2eb;
max-height: 640px;
opacity: 1;
pointer-events: auto;
}
.sc-timeline-wrap.is-focus {
background: #f2f9ff;
border-radius: 8px;
}
.sc-timeline-title {
margin: 0 0 10px;
color: #12344d;
font-size: 14px;
font-weight: 700;
letter-spacing: .01em;
}
.sc-timeline {
list-style: none;
margin: 0;
padding: 0 0 0 18px;
position: relative;
}
.sc-timeline:before {
content: "";
position: absolute;
left: 5px;
top: 2px;
bottom: 2px;
width: 2px;
background: #c8d8e6;
}
.sc-timeline-item {
position: relative;
padding: 0 0 14px 16px;
}
.sc-timeline-item:last-child {
padding-bottom: 0;
}
.sc-timeline-item:before {
content: "";
position: absolute;
left: -18px;
top: 4px;
width: 10px;
height: 10px;
border-radius: 50%;
background: #92a9bf;
box-shadow: 0 0 0 2px #92a9bf;
border: 2px solid #fff;
}
.sc-timeline-item.done:before {
background: #1ab04a;
box-shadow: 0 0 0 2px #1ab04a;
}
.sc-timeline-item.pending:before {
background: #e6a229;
box-shadow: 0 0 0 2px #e6a229;
}
.sc-timeline-title-row {
display: flex;
align-items: baseline;
gap: 8px;
flex-wrap: wrap;
}
.sc-timeline-event {
color: #18354f;
font-size: 14px;
font-weight: 700;
}
.sc-timeline-time {
color: #6b7f92;
font-size: 12px;
font-weight: 500;
}
.sc-timeline-detail {
margin-top: 3px;
color: #3e556b;
font-size: 13px;
}
#tbCotacao {
table-layout: fixed;
width: 100%;
margin-bottom: 0;
}
#tbCotacao thead th {
background: #eef3f8;
color: #3b4d5f;
font-weight: 700;
}
#tbCotacao tbody tr:nth-child(odd) {
background: #f9fbfd;
}
#tbCotacao tbody td,
#tbCotacao thead th,
#tbCotacao tfoot td {
vertical-align: middle;
}
#tbCotacao th:nth-child(3),
#tbCotacao th:nth-child(4),
#tbCotacao th:nth-child(5),
#tbCotacao td:nth-child(3),
#tbCotacao td:nth-child(4),
#tbCotacao td:nth-child(5) {
text-align: right;
}
#tbCotacao td:nth-child(3) input,
#tbCotacao td:nth-child(4) input,
#tbCotacao td:nth-child(5) input {
text-align: right;
}
#tbCotacao tfoot .sc-total-label {
text-align: right;
font-weight: 700;
background: #edf3f8;
color: #324a60;
}
#tbCotacao tfoot .sc-total-value {
background: #edf3f8;
color: #12344d;
font-size: 15px;
font-weight: 700;
text-align: right;
}
@media (max-width: 992px) {
.sc-primary-grid,
.sc-secondary-grid {
grid-template-columns: repeat(2, minmax(180px, 1fr));
}
}
@media (max-width: 640px) {
.sc-primary-grid,
.sc-secondary-grid {
grid-template-columns: 1fr;
}
.sc-info--primary .sc-value {
font-size: 24px;
}
}
</style>
</head>
<body>
<div class="fluig-style-guide" style="background-color:white;">
<h1 id="rcorners" style="margin:0;">Solicitação de compra</h1>
<ul id="wizard-steps" class="steps m-t-20">
<li class="step-item"><span class="step-bullet"></span><span class="step-label">Solicitação</span></li>
<li class="step-item"><span class="step-bullet"></span><span class="step-label">Validando necessidade</span></li>
<li class="step-item"><span class="step-bullet"></span><span class="step-label">Solicitando...</span></li>
<li class="step-item"><span class="step-bullet"></span><span class="step-label">Dados Adicionais</span></li>
<li class="step-item"><span class="step-bullet"></span><span class="step-label">Indicar Cotação</span></li>
<li class="step-item"><span class="step-bullet"></span><span class="step-label">Confirmação Cotação</span></li>
<li class="step-item"><span class="step-bullet"></span><span class="step-label">Aprovação Ccusto</span></li>
<li class="step-item"><span class="step-bullet"></span><span class="step-label">Aprovação GERF</span></li>
<li class="step-item"><span class="step-bullet"></span><span class="step-label">Aprovação CEO</span></li>
<li class="step-item"><span class="step-bullet"></span><span class="step-label">Receber Produto</span></li>
<li class="step-item"><span class="step-bullet"></span><span class="step-label">Problema</span></li>
<li class="step-item"><span class="step-bullet"></span><span class="step-label">Fim</span></li>
</ul>
<form name="form" role="form">
<!-- Campos ocultos -->
<input type="hidden" id="WKNumProces" name="WKNumProces">
@@ -115,10 +369,6 @@
<div class="row">
<div class="col-md-12">
<h2><i class="flaticon flaticon-tests-central icon-md" aria-hidden="true"></i>Dados da solicitação</h2>
<button type="button" class="btn btn-info btn-sm" id="btnHistorico"
style="background-color:#04506b; border-color:#04506b;">
<i class="fluigicon fluigicon-eye-open"></i> Ver Histórico
</button>
<h6>Dados referentes aos responsáveis pela abertura e pela solicitação do atual processo.</h6>
</div>
</div>
@@ -154,11 +404,16 @@
<input type="zoom" class="form-control" name="estabelecimento" id="estabelecimento" data-zoom="{
'displayKey':'LOJA',
'placeholder': 'Buscar nome do estabelecimento ou filial',
'datasetId':'dsSysCompan',
'datasetId':'dsFiliais',
'fields':[
{'field':'LOJA','label':'Filial','standard':'true','search':'true'},
{'field':'CNPJ','label':'CNPJ','standard':'true'},
{'field':'ESTADO','label':'ESTADO','standard':'true'}
{'field':'REGIONAL','label':'REGIONAL','standard':'true'},
{'field':'UF','label':'UF','standard':'true'},
{'field':'RESPONSAVEL_LOJA','label':'RESPONSAVEL_LOJA','visible':'false'},
{'field':'PDV','label':'PDV','visible':'false'},
{'field':'PROTHEUS','label':'PROTHEUS','visible':'false'},
{'field':'COLLEAGUE_ID','label':'COLLEAGUE_ID','visible':'false'},
{'field':'LOGIN_LOJA','label':'LOGIN_LOJA','visible':'false'}
]
}">
<p class="help-block" id="estabelecimentoFilial" style="display:none;position:absolute;font-size:12px;">
@@ -166,19 +421,9 @@
</p>
</div>
<div class="form-group col-md-3 col-xs-12 divCentroCusto alertaCampo">
<label for="zoom">Centro de custo <span class="required text-danger"><strong>*</strong></span></label>
<input type="zoom" class="form-control" name="centro_custo" id="centro_custo" data-zoom="{
'displayKey':'centroCusto',
'placeholder': 'Buscar número ou nome do centro de custo',
'datasetId':'ds_centroCusto',
'fields':[
{'field':'codigoCentroCusto','label':'Código','standard':'true','search':'true'},
{'field':'centroCusto','label':'Nome','search':'true'},
{'field':'gestorCentroCusto','label':'gestorCentroCusto','visible':'false'},
{'field':'idGestor','label':'idGestor','visible':'false'},
{'field':'emailGestor','label':'emailGestor','visible':'false'}
]
}">
<label>Gestor da loja <span class="required text-danger"><strong>*</strong></span></label>
<input type="text" class="form-control" name="centro_custo" id="centro_custo"
placeholder="Será preenchido automaticamente ao selecionar a filial" readonly>
<p class="help-block" id="centroCusto" style="display:none;position:absolute;font-size:12px;">
Preenchimento obrigatório
</p>
@@ -364,37 +609,53 @@
</div>
</div>
<div class="card" style="margin-top:15px; border-radius:8px; box-shadow:0 2px 5px rgba(0,0,0,0.1);">
<div class="card-body" style="padding:15px; background-color:#f9f9f9;">
<div class="row">
<div class="col-md-4">
<p><strong>Número:</strong> <span id="numeroSCProtheus_label">-</span></p>
</div>
<div class="col-md-4">
<p><strong>Status:</strong> <span id="statusSCProtheus_label" class="badge bg-secondary">-</span></p>
</div>
<div class="col-md-4">
<p><strong>Solicitante:</strong> <span id="solicitanteSCProtheus_label">-</span></p>
</div>
<div class="col-md-4">
<p><strong>Emissão:</strong> <span id="emissaoSCProtheus_label">-</span></p>
</div>
<div class="col-md-4">
<p><strong>Qtd. Itens:</strong> <span id="qtdItensSCProtheus_label">-</span></p>
</div>
<div class="col-md-4">
<p><strong>Data da aprovação:</strong> <span id="dataCadastroSCProtheus_label">-</span> às <span id="horaCadastroSCProtheus_label">-</span></p>
</div>
<div class="col-md-4">
<p><strong>Status:</strong> <span id="statusSC_label" class="badge bg-secondary">-</span></p>
</div>
<div class="col-md-4">
<p><strong>Cotação:</strong> <span id="cotacaoSC_label">-</span></p>
</div>
<div class="col-md-4">
<p><strong>Pedido:</strong> <span id="pedidoSC_label">-</span></p>
</div>
<div class="sc-status-panel">
<div class="sc-primary-grid">
<div class="sc-info sc-info--primary sc-info--clickable" id="cardNumeroSC" title="Clique para ver a linha do tempo da SC">
<div class="sc-label">Número SC</div>
<div class="sc-value" id="numeroSCProtheus_label">-</div>
<span class="sc-hint" id="cardNumeroSCHint">Clique para ver a linha do tempo</span>
</div>
<div class="sc-info sc-info--primary">
<div class="sc-label">Status Cadastro</div>
<span class="sc-value badge bg-secondary" id="statusSCProtheus_label">-</span>
</div>
<div class="sc-info sc-info--primary">
<div class="sc-label">Andamento</div>
<span class="sc-value badge bg-secondary" id="statusSC_label">-</span>
</div>
</div>
<div class="sc-secondary-grid">
<div class="sc-info sc-info--secondary">
<div class="sc-label">Solicitante</div>
<div class="sc-value" id="solicitanteSCProtheus_label">-</div>
</div>
<div class="sc-info sc-info--secondary">
<div class="sc-label">Emissão</div>
<div class="sc-value" id="emissaoSCProtheus_label">-</div>
</div>
<div class="sc-info sc-info--secondary">
<div class="sc-label">Qtd. Itens</div>
<div class="sc-value" id="qtdItensSCProtheus_label">-</div>
</div>
<div class="sc-info sc-info--secondary">
<div class="sc-label">Data do Cadastro</div>
<div class="sc-value"><span id="dataCadastroSCProtheus_label">-</span> às <span id="horaCadastroSCProtheus_label">-</span></div>
</div>
<div class="sc-info sc-info--secondary">
<div class="sc-label">Cotação</div>
<div class="sc-value" id="cotacaoSC_label">-</div>
</div>
<div class="sc-info sc-info--secondary">
<div class="sc-label">Pedido</div>
<div class="sc-value" id="pedidoSC_label">-</div>
</div>
</div>
<div class="sc-timeline-wrap" id="scTimelineSection">
<h4 class="sc-timeline-title">Linha do tempo da SC</h4>
<ul class="sc-timeline" id="scTimeline"></ul>
</div>
</div>
</div>
@@ -430,6 +691,13 @@
<td><input type="checkbox" name="selecionado" id="selecionado" value="S"></td>
</tr>
</tbody>
<tfoot>
<tr>
<td colspan="4" class="sc-total-label">Total selecionado</td>
<td class="sc-total-value" id="valorTotalCotacaoLabel">R$ 0,00</td>
<td></td>
</tr>
</tfoot>
</table>
</div>
</div>
@@ -46,15 +46,21 @@ function recalcTotal() {
function setSelectedZoomItem(selectedItem) {
if (selectedItem.inputId === "estabelecimento") {
// joga o código da filial (cnpj, etc.)
$("#filialdest").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
$("#filialprotheus").val(selectedItem.CODIGO); // supondo que o dataset dsSysCompany devolva o campo CODIGO
}
if (selectedItem.inputId === "centro_custo") {
// joga o código da filial (cnpj, etc.)
$("#gestor_cc").val(selectedItem.idGestor); // supondo que o dataset Centro_custo devolva o campo GestorCentroCusto
$("#codigocentroCusto").val(selectedItem.codigoCentroCusto); // supondo que o dataset Centro_custo devolva o campo GestorCentroCusto
// dsFiliais: guarda dados da filial e define gestor da próxima atividade
var codigoProtheus = String(selectedItem.PROTHEUS || selectedItem.protheus || "").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.");
}
}
@@ -62,14 +68,18 @@ function setSelectedZoomItem(selectedItem) {
function removedZoomItem(removedItem) {
if (removedItem.inputId === "estabelecimento") {
// Quando remover a empresa, limpa os campos relacionados
$("#filialDesc").val('');
$("#filialest").val('');
// Quando remover a filial, limpa os campos relacionados
$("#filialdest").val("");
$("#filialest").val("");
$("#filialprotheus").val("");
$("#centro_custo").val("");
$("#codigocentroCusto").val("");
$("#gestor_cc").val("");
}
}
/* ========= Config ========= */
const DATASET_PRODUTOS = "dsProd"; // dataset de produtos
const DATASET_PRODUTOS = "dsComprasProdutos"; // dataset de produtos
let todosProdutos = [];
let paginaAtual = 1;
const itensPorPagina = 10;
@@ -120,7 +130,10 @@ 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 : [];
const values = dataset && dataset.values ? dataset.values : [];
todosProdutos = values
.map(normalizarProduto)
.filter(p => p.codigo && p.descricao);
console.log("Produtos carregados do dataset:", todosProdutos.length);
}
@@ -171,10 +184,10 @@ function renderizaProdutos(filtro) {
</tr>`;
} else {
produtosPagina.forEach(produto => {
const codigo = escapeHTML(produto['codigo']);
const descricao = escapeHTML(produto['descricao']);
const um = escapeHTML(produto['medida'] || '');
const preco = produto['ultimo_preco'] || '0,00';
const codigo = escapeHTML(produto.codigo);
const descricao = escapeHTML(produto.descricao);
const um = escapeHTML(produto.medida || '');
const preco = produto.ultimo_preco || '0,00';
html += `
<tr>
@@ -200,6 +213,15 @@ function renderizaProdutos(filtro) {
renderizaPaginacao(produtosFiltrados.length);
}
function normalizarProduto(row) {
return {
codigo: String(row.B1_COD || row.codigo || "").trim(),
descricao: String(row.B1_DESC || row.descricao || "").trim(),
medida: String(row.B1_UM || row.medida || "").trim(),
ultimo_preco: String(row.B1_UPRC || row.ultimo_preco || "0,00").trim()
};
}
function renderizaPaginacao(totalItens) {
@@ -375,29 +397,325 @@ $(function () {
});
function valorCampo(id) {
return String($("#" + id).val() || "").trim();
}
function setLabel(id, valor) {
var texto = String(valor || "").trim();
$("#" + id).text(texto || "-");
}
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("sucesso") >= 0 || s.indexOf("aprov") >= 0 || s.indexOf("gerad") >= 0 || s.indexOf("liberad") >= 0) return "badge bg-success";
if (s.indexOf("aguard") >= 0 || s.indexOf("pend") >= 0) return "badge bg-warning";
return "badge bg-info";
}
function setBadge(selector, valor) {
var texto = String(valor || "").trim() || "-";
$(selector)
.text(texto)
.removeClass("bg-secondary bg-success bg-danger bg-warning bg-info")
.addClass(badgeClassByStatus(texto));
}
function normalizarStatusCadastro(statusCadastro, numeroSC) {
var numero = String(numeroSC || "").trim();
var status = String(statusCadastro || "").trim();
var s = status.toLowerCase();
if (!numero) return status;
if (!status) return "SC cadastrada com sucesso";
if (s.indexOf("sucesso") >= 0 || s.indexOf("cadastr") >= 0) return "SC cadastrada com sucesso";
return status;
}
function normalizarAndamento(andamento, cotacao, pedido) {
var atual = String(andamento || "").trim();
if (pedido) return "Pedido gerado";
if (cotacao && (!atual || atual.toLowerCase().indexOf("pedido") < 0)) return "Cotacao gerada";
return atual;
}
function normalizarDataProtheus(data) {
var d = String(data || "").trim();
if (/^\d{8}$/.test(d)) {
return d.substring(6, 8) + "/" + d.substring(4, 6) + "/" + d.substring(0, 4);
}
return d;
}
function limparNumeroDocumento(valor) {
var v = String(valor || "").trim();
if (!v || /^0+$/.test(v)) return "";
return v;
}
function comporDataHora(data, hora) {
var d = String(data || "").trim();
var h = String(hora || "").trim();
if (d && h && h !== "-") return d + " as " + h;
return d || h || "";
}
function montarEventosTimelineSC(dados) {
var eventos = [];
var momentoSolicitacao = comporDataHora(dados.dataCadastro, dados.horaCadastro);
var momentoSC = dados.emissao || momentoSolicitacao;
eventos.push({
classe: (dados.numero || dados.solicitante || momentoSolicitacao) ? "done" : "pending",
titulo: "Solicitacao criada",
momento: momentoSolicitacao,
detalhe: dados.solicitante ? "Solicitante: " + dados.solicitante : ""
});
if (dados.numero) {
eventos.push({
classe: "done",
titulo: "SC " + dados.numero + " cadastrada",
momento: momentoSC,
detalhe: dados.statusCadastro ? "Status: " + dados.statusCadastro : ""
});
} else {
eventos.push({
classe: "pending",
titulo: "Aguardando geracao da SC",
momento: "",
detalhe: "A SC sera exibida assim que for criada no Protheus."
});
}
if (dados.cotacao) {
eventos.push({
classe: "done",
titulo: "Cotacao " + dados.cotacao + " gerada",
momento: "",
detalhe: "Cotacao disponivel para analise."
});
} else {
eventos.push({
classe: "pending",
titulo: "Aguardando cotacao",
momento: "",
detalhe: "Ainda nao existe cotacao vinculada a SC."
});
}
if (dados.pedido) {
eventos.push({
classe: "done",
titulo: "Pedido " + dados.pedido + " gerado",
momento: "",
detalhe: "Compra convertida em pedido."
});
} else {
eventos.push({
classe: "pending",
titulo: "Aguardando pedido",
momento: "",
detalhe: "O pedido sera criado apos a aprovacao final da cotacao."
});
}
return eventos;
}
function renderizarTimelineSC(dados) {
var eventos = montarEventosTimelineSC(dados);
var html = eventos.map(function (evento) {
var titulo = escapeHTML(evento.titulo);
var momento = escapeHTML(evento.momento || "");
var detalhe = escapeHTML(evento.detalhe || "");
var classe = evento.classe === "done" ? "done" : "pending";
return [
'<li class="sc-timeline-item ' + classe + '">',
' <div class="sc-timeline-title-row">',
' <span class="sc-timeline-event">' + titulo + '</span>',
momento ? (' <span class="sc-timeline-time">' + momento + '</span>') : "",
" </div>",
detalhe ? (' <div class="sc-timeline-detail">' + detalhe + "</div>") : "",
"</li>"
].join("");
}).join("");
$("#scTimeline").html(html);
}
function focarTimelineSC() {
var secao = $("#scTimelineSection");
if (!secao.length) return;
secao.addClass("is-focus");
setTimeout(function () {
secao.removeClass("is-focus");
}, 900);
try {
secao.get(0).scrollIntoView({ behavior: "smooth", block: "nearest" });
} catch (e) {
// fallback para navegadores sem smooth scroll
secao.get(0).scrollIntoView();
}
}
function abrirTimelineSC() {
var secao = $("#scTimelineSection");
if (!secao.length) return;
secao.addClass("is-open");
$("#cardNumeroSCHint").text("Clique para ocultar a linha do tempo");
}
function fecharTimelineSC() {
var secao = $("#scTimelineSection");
if (!secao.length) return;
secao.removeClass("is-open is-focus");
$("#cardNumeroSCHint").text("Clique para ver a linha do tempo");
}
function alternarTimelineSC() {
var secao = $("#scTimelineSection");
if (!secao.length) return;
if (secao.hasClass("is-open")) {
fecharTimelineSC();
return;
}
abrirTimelineSC();
focarTimelineSC();
}
function montarStatusAndamento(scRow, cotacao, pedido) {
if (pedido) return "Pedido gerado";
if (cotacao) return "Cotacao gerada";
var statusApi = String(scRow.STATUS || "").trim();
if (statusApi) return statusApi;
var aprov = String(scRow.C1_APROV || "").trim().toUpperCase();
if (aprov === "B") return "Aguardando cotacao";
if (aprov === "L") return "Liberada";
if (aprov === "R") return "Reprovada";
if (aprov) return "Status Protheus: " + aprov;
return "";
}
function preencherResumoSC() {
var numero = valorCampo("numeroSCProtheus");
var statusCadastro = valorCampo("statusSCProtheus");
var solicitante = valorCampo("solicitanteSCProtheus");
var emissao = normalizarDataProtheus(valorCampo("emissaoSCProtheus"));
var qtdItens = valorCampo("qtdItensSCProtheus");
var dataCadastro = normalizarDataProtheus(valorCampo("dataCadastroSCProtheus"));
var horaCadastro = valorCampo("horaCadastroSCProtheus");
var cotacao = limparNumeroDocumento(valorCampo("cotacaoSCProtheus"));
var pedido = limparNumeroDocumento(valorCampo("pedidoSCProtheus"));
var andamento = valorCampo("statusAtendimento");
var statusCadastroPadrao = normalizarStatusCadastro(statusCadastro, numero);
if (!andamento && numero) {
if (pedido) andamento = "Pedido gerado";
else if (cotacao) andamento = "Cotacao gerada";
else andamento = "Em andamento";
}
andamento = normalizarAndamento(andamento, cotacao, pedido);
setLabel("numeroSCProtheus_label", numero);
setLabel("solicitanteSCProtheus_label", solicitante);
setLabel("emissaoSCProtheus_label", emissao);
setLabel("qtdItensSCProtheus_label", qtdItens);
setLabel("dataCadastroSCProtheus_label", dataCadastro);
setLabel("horaCadastroSCProtheus_label", horaCadastro);
setLabel("cotacaoSC_label", cotacao);
setLabel("pedidoSC_label", pedido);
setBadge("#statusSCProtheus_label", statusCadastroPadrao || (numero ? "SC cadastrada com sucesso" : ""));
setBadge("#statusSC_label", andamento);
renderizarTimelineSC({
numero: numero,
statusCadastro: statusCadastroPadrao,
andamento: andamento,
solicitante: solicitante,
emissao: emissao,
dataCadastro: dataCadastro,
horaCadastro: horaCadastro,
cotacao: cotacao,
pedido: pedido
});
}
function consultarAndamentoSC() {
var numero = valorCampo("numeroSCProtheus");
if (!numero || typeof DatasetFactory === "undefined" || typeof ConstraintType === "undefined") {
return;
}
try {
var cNumero = DatasetFactory.createConstraint("numeroSCProtheus", numero, numero, ConstraintType.MUST);
var ds = DatasetFactory.getDataset("ds_consultaSC", null, [cNumero], null);
var row = (ds && ds.values && ds.values.length > 0) ? ds.values[0] : null;
if (!row) return;
if (String(row.sucesso || "").toLowerCase() !== "true") return;
var cotacao = limparNumeroDocumento(row.C1_COTACAO);
var pedido = limparNumeroDocumento(row.C1_PEDIDO);
if (cotacao) $("#cotacaoSCProtheus").val(cotacao);
if (pedido) $("#pedidoSCProtheus").val(pedido);
if (row.C1_SOLICIT) $("#solicitanteSCProtheus").val(String(row.C1_SOLICIT).trim());
if (row.C1_EMISSAO) $("#emissaoSCProtheus").val(normalizarDataProtheus(row.C1_EMISSAO));
var andamento = montarStatusAndamento(row, cotacao, pedido);
if (andamento) $("#statusAtendimento").val(andamento);
preencherResumoSC();
} catch (e) {
console.warn("Nao foi possivel consultar andamento da SC no ds_consultaSC:", e);
}
}
$(document).ready(function () {
// Quando carregar a página, já pinta o status se tiver valor nos inputs
let status = $("#statusSCProtheus").val() || "";
let badgeClass = "badge bg-secondary";
preencherResumoSC();
consultarAndamentoSC();
if (status.toLowerCase().includes("sucesso")) badgeClass = "badge bg-success";
if (status.toLowerCase().includes("erro")) badgeClass = "badge bg-danger";
$("#statusSCProtheus_label")
.text(status || "-")
.removeClass()
.addClass(badgeClass);
$(document).on("click", "#cardNumeroSC", function () {
alternarTimelineSC();
});
});
function parseNumeroCotacao(valor) {
var texto = String(valor || "").trim();
if (!texto) return 0;
if (texto.indexOf(",") >= 0) {
texto = texto.replace(/\./g, "").replace(",", ".");
}
texto = texto.replace(/[^\d.-]/g, "");
return parseFloat(texto) || 0;
}
function recalcularTotalCotacao() {
var soma = 0;
$("input[name^='selecionado___']").each(function() {
var idx = $(this).attr("id").split("___")[1];
var idCampo = String($(this).attr("id") || "");
if (idCampo.indexOf("___") < 0) return;
var idx = idCampo.split("___")[1];
// pega qtd e preço da linha
var qtd = parseFloat($("#qtdc___" + idx).val() || "0");
var preco = parseFloat($("#preco___" + idx).val() || "0");
var qtd = parseNumeroCotacao($("#qtdc___" + idx).val() || "0");
var preco = parseNumeroCotacao($("#preco___" + idx).val() || "0");
// calcula total da linha
var total = qtd * preco;
@@ -413,6 +731,7 @@ function recalcularTotalCotacao() {
// Atualiza o hidden e dispara change pro Fluig gravar
$("#valorTotalCotacao").val(soma.toFixed(2)).trigger("change");
$("#valorTotalCotacaoLabel").text(floatToBRL(soma));
}
// dispara sempre que marcar/desmarcar
$(document).on("change", "input[name^='selecionado___']", function() {
@@ -1,283 +1,55 @@
function displayFields(form, customHTML) {
var activity = getValue('WKNumState');
var userId = getValue('WKUser');
var activity = parseInt(getValue("WKNumState"), 10);
var userId = getValue("WKUser");
var hoje = new java.text.SimpleDateFormat("dd/MM/yyyy").format(new java.util.Date());
form.setShowDisabledFields(true);
form.setHidePrintLink(true);
form.setValue("WKNumProces", getValue('WKNumProces'));
form.setValue("activity", activity);
form.setValue("WKNumProces", getValue("WKNumProces"));
form.setValue("activity", String(activity));
form.setValue("formMode", form.getFormMode());
form.setValue("empresa", getValue("WKCompany"));
var c1 = DatasetFactory.createConstraint("colleagueId", userId, userId, ConstraintType.MUST);
var filter = new Array(c1);
var fields = new Array("colleagueName");
var retorno = DatasetFactory.getDataset("colleague", fields, filter, null);
var nomeUsuario = "";
var emailUsuario = "";
//requester
if (activity == 0) {
form.setValue("usuario_abertura", retorno.getValue(0, "colleagueName"));
form.setValue("requesterMail", retorno.getValue(0, "mail"));
form.setValue("requesterId", userId);
} else {
form.setValue("currentUserName", retorno.getValue(0, "colleagueName"));
form.setValue("currentUsermail", retorno.getValue(0, "mail"));
form.setValue("currentUserId", userId);
try {
var c1 = DatasetFactory.createConstraint("colleagueId", userId, userId, ConstraintType.MUST);
var constraints = [c1];
var fields = ["colleagueName", "mail"];
var dsColleague = DatasetFactory.getDataset("colleague", fields, constraints, null);
if (dsColleague && dsColleague.rowsCount > 0) {
nomeUsuario = dsColleague.getValue(0, "colleagueName") || "";
emailUsuario = dsColleague.getValue(0, "mail") || "";
}
} catch (e) {
log.error("[displayFields] Erro ao consultar colleague: " + e);
}
// ✅ Quando for atividade de aprovação do gestor
if (activity == 121) {
var hoje = new java.text.SimpleDateFormat("dd/MM/yyyy").format(new java.util.Date());
form.setValue("user_validacao_gestor", retorno.getValue(0, "colleagueName"));
form.setValue("currentUserName", nomeUsuario);
form.setValue("currentUsermail", emailUsuario);
form.setValue("currentUserId", userId);
if (activity === 0 || activity === 1) {
form.setValue("requesterId", userId);
if (emailUsuario) {
form.setValue("requesterMail", emailUsuario);
}
if (!form.getValue("usuarioSolicitante") && nomeUsuario) {
form.setValue("usuarioSolicitante", nomeUsuario);
}
if (!form.getValue("emailSolicitante") && emailUsuario) {
form.setValue("emailSolicitante", emailUsuario);
}
}
if (activity === 121) {
if (nomeUsuario) {
form.setValue("user_validacao_gestor", nomeUsuario);
}
form.setValue("data_validacao_gestor", hoje);
}
if (activity == 133) {
var hoje = new java.text.SimpleDateFormat("dd/MM/yyyy").format(new java.util.Date());
form.setValue("gestor_validacao_aprova", retorno.getValue(0, "colleagueName"));
form.setValue("data_validacao_aprova_gestor", hoje);
}
if (activity == 137) {
var hoje = new java.text.SimpleDateFormat("dd/MM/yyyy").format(new java.util.Date());
form.setValue("user_validacao_aprova", retorno.getValue(0, "colleagueName"));
form.setValue("data_validacao_aprova", hoje);
}
if (activity == 147) {
var hoje = new java.text.SimpleDateFormat("dd/MM/yyyy").format(new java.util.Date());
form.setValue("gerf_validacao_aprova", retorno.getValue(0, "colleagueName"));
form.setValue("data_validacao_aprova_gerf", hoje);
}
if (activity == 18) {
var hoje = new java.text.SimpleDateFormat("dd/MM/yyyy").format(new java.util.Date());
form.setValue("userValidacaoItens", retorno.getValue(0, "colleagueName"));
form.setValue("dataValidacaoItens", hoje);
}
// ✅ Injetar dados da SC do Protheus (se já tiverem sido preenchidos no servicetask)
var camposSC = [
"numeroSCProtheus",
"statusSCProtheus",
"solicitanteSCProtheus",
"emissaoSCProtheus",
"qtdItensSCProtheus",
"dataCadastroSCProtheus",
"horaCadastroSCProtheus"
];
camposSC.forEach(function(campo) {
var valor = form.getValue(campo);
if (valor) {
customHTML.append("<script>$('#" + campo + "_label').text('" + valor + "');</script>");
}
});
// cor no status
var status = form.getValue("statusSCProtheus");
if (status) {
var badgeClass = "badge bg-secondary";
if (status.toLowerCase().indexOf("sucesso") >= 0) badgeClass = "badge bg-success";
if (status.toLowerCase().indexOf("erro") >= 0) badgeClass = "badge bg-danger";
customHTML.append("<script>$('#statusSCProtheus_label').removeClass().addClass('" + badgeClass + "').text('" + status + "');</script>");
}
// Consultar informações adicionais da SC no Protheus
var numSC = form.getValue("numeroSCProtheus");
if (numSC) {
try {
var c1 = DatasetFactory.createConstraint("numeroSCProtheus", numSC, numSC, ConstraintType.MUST);
var ds = DatasetFactory.getDataset("ds_consultaSC", null, [c1], null);
if (ds && ds.rowsCount > 0) {
var status = ds.getValue(0, "STATUS") || "";
var cotacao = ds.getValue(0, "C1_COTACAO") || "";
var pedido = ds.getValue(0, "C1_PEDIDO") || "";
// grava nos hidden inputs
form.setValue("statusAtendimento", status);
form.setValue("cotacaoSCProtheus", cotacao);
form.setValue("pedidoSCProtheus", pedido);
// mostra nos cards (HTML)
customHTML.append("<script>$('#statusSC_label').text('" + status + "');</script>");
customHTML.append("<script>$('#cotacaoSC_label').text('" + cotacao + "');</script>");
customHTML.append("<script>$('#pedidoSC_label').text('" + pedido + "');</script>");
}
} catch (e) {
log.error("❌ Erro ao consultar dataset ds_consultaSC: " + e);
}
}
try {
var msgs = [];
var numeroSC = form.getValue("numeroSCProtheus");
var cotacaoSC = form.getValue("cotacaoSCProtheus");
var pedidoSC = form.getValue("pedidoSCProtheus");
if (numeroSC) msgs.push("📌 Gerou SC Protheus nº " + numeroSC);
if (cotacaoSC) msgs.push("📌 SC originou Cotação nº " + cotacaoSC);
if (pedidoSC) msgs.push("📌 Cotação finalizou → Pedido nº " + pedidoSC);
if (msgs.length === 0) {
msgs.push("️ Nenhum dado de integração Protheus encontrado no formulário");
}
// Monta conteúdo HTML do histórico
var htmlHistorico = "<ul class='hist-list'>";
for (var i = 0; i < msgs.length; i++) {
htmlHistorico += "<li class='hist-item'>" + msgs[i] + "</li>";
}
htmlHistorico += "</ul>";
// Script para abrir modal ao clicar no botão
customHTML.append("<script>");
customHTML.append("$('#btnHistorico').off('click').on('click', function(){");
customHTML.append(" var myModal = FLUIGC.modal({");
customHTML.append(" title: 'Histórico do Processo',");
customHTML.append(" content: `" + htmlHistorico + "`,");
customHTML.append(" id: 'modalHistorico',");
customHTML.append(" size: 'large'");
customHTML.append(" });");
customHTML.append("});");
customHTML.append("</script>");
} catch (e) {
log.error("[displayFields] Erro ao montar histórico: " + e);
}
var numCot = form.getValue("cotacaoSCProtheus");
var numSC = form.getValue("numeroSCProtheus"); // pega a SC atual
function formatCurrency(v) {
if (!v || isNaN(v)) return "R$ 0,00";
var num = parseFloat(v).toFixed(2);
return "R$ " + num.replace(".", ",").replace(/\B(?=(\d{3})+(?!\d))/g, ".");
}
function formatDate(v) {
if (!v || v.length !== 8) return v || "";
var y = v.substring(0,4);
var m = v.substring(4,6);
var d = v.substring(6,8);
return d + "/" + m + "/" + y;
}
function formatPrazo(v) {
if (!v) return "";
return v + " dias úteis";
}
if (!numCot) {
customHTML.append("<script>");
customHTML.append("$('#cotacaoContainer').html('<p>⚠️ Cotação não informada no formulário.</p>');");
customHTML.append("</script>");
return;
}
var c = DatasetFactory.createConstraint("numCotacao", numCot, numCot, ConstraintType.MUST);
var ds = DatasetFactory.getDataset("dsComprasCotacao", null, [c], null);
var precoFormatado = formatCurrency(preco);
var totalFormatado = formatCurrency(total);
if (ds && ds.rowsCount > 0) {
for (var i = 0; i < ds.rowsCount; i++) {
var item = ds.getValue(i, "C8_ITEM");
var desc = ds.getValue(i, "B1_DESC");
var qtd = ds.getValue(i, "C8_QUANT");
var preco = ds.getValue(i, "C8_PRECO");
var total = ds.getValue(i, "C8_TOTAL");
// adiciona linha na tabela pai-filho
customHTML.append("<script>");
customHTML.append("var idx = wdkAddChild('tbCotacao');");
customHTML.append("$('#item___'+idx).val('" + item + "');");
customHTML.append("$('#produto___'+idx).val('" + desc + "');");
customHTML.append("$('#qtdc___'+idx).val('" + qtd + "');");
customHTML.append("$('#preco___' + idx).val('" + precoFormatado + "');");
customHTML.append("$('#total___' + idx).val('" + totalFormatado + "');");
customHTML.append("</script>");
}
} else {
customHTML.append("<script>$('#tbCotacao tbody').html('<tr><td colspan=6>⏳ Nenhum item encontrado.</td></tr>');</script>");
}
try {
var numPedido = form.getValue("pedidoSCProtheus"); // hidden no formulário
if (!numPedido) {
customHTML.append("<script>");
customHTML.append("$('#espelhoPedido').html('<span class=\"badge bg-warning\">⏳ O pedido ainda não foi criado</span>');");
customHTML.append("</script>");
return;
}
var c = DatasetFactory.createConstraint("numeroPed", numPedido, numPedido, ConstraintType.MUST);
var ds = DatasetFactory.getDataset("dsComprasGateway", null, [c], null);
if (!ds || ds.rowsCount === 0) {
customHTML.append("<script>");
customHTML.append("$('#espelhoPedido').html('<span class=\"badge bg-warning\">⏳ O pedido ainda não foi criado</span>');");
customHTML.append("</script>");
return;
}
var html = "";
for (var i = 0; i < ds.rowsCount; i++) {
var rowNum = ds.getValue(i, "C7_NUM");
var desc = ds.getValue(i, "B1_DESC");
var qtd = ds.getValue(i, "C7_QUANT");
var valor = ds.getValue(i, "C7_TOTAL");
var un = ds.getValue(i, "B1_UM");
var pr = ds.getValue(i, "C7_DATPRF");
html += "<div class='pedido-card'>"
+ " <div class='pedido-header'>Pedido nº " + (rowNum || "-") + "</div>"
+ " <div class='pedido-grid'>"
+ " <div class='pedido-box'><b>Descrição</b><br>" + (desc || "-") + "</div>"
+ " <div class='pedido-box'><b>Quantidade</b><br>" + parseInt(qtd || 0) + " " + (un || "") + "</div>"
+ " <div class='pedido-box'><b>Valor</b><br>" + formatCurrency(valor) + "</div>"
+ " <div class='pedido-box'><b>Data de Entrega</b><br>" + formatDate(pr) + "</div>"
+ " </div>"
+ "</div>";
}
customHTML.append("<script>");
customHTML.append("$('#espelhoPedido').html(" + JSON.stringify(html) + ");");
customHTML.append("</script>");
} catch (e) {
var msg = "❌ Erro displayFields Pedido: " + (e && e.message ? e.message : e);
log.error(msg);
customHTML.append("<script>");
customHTML.append("console.error(" + JSON.stringify(msg) + ");"); // aparece no console do navegador
customHTML.append("$('#espelhoPedido').html('<span class=\"badge bg-danger\">" + msg + "</span>');");
customHTML.append("</script>");
}
// Se estou na atividade do Gestor do CC (ex: 133)
if (activity == 133) {
// Copia a justificativa do solicitante para o campo de exibição
form.setValue("observacoesdosolicitante", form.getValue("observacoes"));
}
// Se estou na atividade do GERF (ex: 147)
if (activity == 147) {
form.setValue("justi_decisao__soli", form.getValue("observacoes")); // solicitante
form.setValue("justi_decisao_gc", form.getValue("justi_decisao_aprova_gestor")); // gestor
}
// Se estou na atividade do CEO (ex: 158)
if (activity == 158) {
form.setValue("justi_decisao_solic", form.getValue("observacoes")); // solicitante
form.setValue("justi_decisaogc", form.getValue("justi_decisao_aprova_gestor")); // gestor
form.setValue("justi_decisao_gerf", form.getValue("justi_decisao_aprova_gerente")); // gerente financeiro
}
}
}
@@ -2,6 +2,12 @@ function validateForm(form){
var msg = "";
var activity = getValue("WKNumState");
if (activity == 0 || activity == 1) {
if (form.getValue("gestor_cc") == "") {
msg += "Não foi possível identificar o gestor da loja selecionada. Selecione a filial novamente.\n";
}
}
// Só valida "Justificativa do Gestor" quando estiver na atividade do gestor (ex.: 5)
if (activity == 121) {
if (form.getValue("justi_decisao_gestor") == "") {
@@ -12,4 +18,4 @@ function validateForm(form){
if (msg != "") {
throw msg;
}
}
}