-
-
-
+
+
+
-
-
-
+
+
+
-
-
+
+
-
-
-
+
+
+
-
-
-
-
-
+
+
+
+
+
diff --git a/compras_digital/wcm/widget/widget_solicitacoes/src/main/webapp/resources/css/widget_solicitacoes.css b/compras_digital/wcm/widget/widget_solicitacoes/src/main/webapp/resources/css/widget_solicitacoes.css
index a23359a..b9c22f4 100644
--- a/compras_digital/wcm/widget/widget_solicitacoes/src/main/webapp/resources/css/widget_solicitacoes.css
+++ b/compras_digital/wcm/widget/widget_solicitacoes/src/main/webapp/resources/css/widget_solicitacoes.css
@@ -1 +1,462 @@
-/* Coloque aqui seu codigo CSS */
+.compras-tracker-widget {
+ color: #172033;
+}
+
+.tracker-shell {
+ background: #f7f9fc;
+ border: 1px solid #dfe6ef;
+ border-radius: 8px;
+ padding: 18px;
+}
+
+.tracker-header {
+ align-items: center;
+ display: flex;
+ gap: 16px;
+ justify-content: space-between;
+ margin-bottom: 16px;
+}
+
+.tracker-header h2 {
+ color: #101828;
+ font-size: 22px;
+ font-weight: 700;
+ line-height: 1.2;
+ margin: 0 0 4px;
+}
+
+.tracker-header p {
+ color: #667085;
+ font-size: 13px;
+ margin: 0;
+}
+
+.tracker-search,
+.tracker-card,
+.tracker-table-wrap {
+ background: #fff;
+ border: 1px solid #d9e2ec;
+ border-radius: 8px;
+ box-shadow: 0 8px 22px rgba(16, 24, 40, .05);
+}
+
+.tracker-search {
+ margin-bottom: 14px;
+ padding: 16px;
+}
+
+.tracker-search label {
+ color: #344054;
+ font-size: 12px;
+ font-weight: 700;
+}
+
+.tracker-search-actions .btn {
+ margin-top: 0;
+}
+
+.tracker-refresh {
+ align-items: center;
+ display: inline-flex;
+ gap: 6px;
+ white-space: nowrap;
+}
+
+.tracker-message:empty {
+ display: none;
+}
+
+.tracker-results {
+ margin-bottom: 14px;
+}
+
+.tracker-table-wrap {
+ overflow-x: auto;
+}
+
+.tracker-table {
+ margin: 0;
+}
+
+.tracker-table > thead > tr > th {
+ background: #f8fafc;
+ border-bottom: 1px solid #d9e2ec;
+ color: #344054;
+ font-size: 12px;
+ white-space: nowrap;
+}
+
+.tracker-table > tbody > tr > td {
+ color: #344054;
+ font-size: 13px;
+ vertical-align: middle;
+}
+
+.tracker-detail {
+ margin-top: 14px;
+}
+
+.tracker-card {
+ margin-bottom: 14px;
+ padding: 16px;
+}
+
+.tracker-card-main {
+ padding: 18px;
+}
+
+.tracker-title-row,
+.tracker-section-head {
+ align-items: center;
+ display: flex;
+ gap: 12px;
+ justify-content: space-between;
+}
+
+.tracker-title-row {
+ margin-bottom: 16px;
+}
+
+.tracker-title-row h3 {
+ color: #101828;
+ font-size: 20px;
+ font-weight: 700;
+ margin: 0 0 3px;
+}
+
+.tracker-title-row span {
+ color: #667085;
+ font-size: 12px;
+}
+
+.tracker-summary-grid {
+ display: grid;
+ gap: 12px;
+ grid-template-columns: repeat(3, minmax(0, 1fr));
+}
+
+.tracker-info {
+ background: #fbfcfe;
+ border: 1px solid #e6edf5;
+ border-radius: 6px;
+ min-height: 68px;
+ padding: 10px 12px;
+}
+
+.tracker-info span {
+ color: #667085;
+ display: block;
+ font-size: 11px;
+ font-weight: 700;
+ margin-bottom: 7px;
+ text-transform: uppercase;
+}
+
+.tracker-info strong {
+ color: #172033;
+ display: block;
+ font-size: 14px;
+ line-height: 1.25;
+ overflow-wrap: anywhere;
+}
+
+.tracker-steps {
+ align-items: flex-start;
+ display: grid;
+ grid-template-columns: repeat(5, minmax(96px, 1fr));
+ position: relative;
+}
+
+.tracker-steps:before {
+ background: #cfd8e3;
+ content: "";
+ height: 2px;
+ left: 10%;
+ position: absolute;
+ right: 10%;
+ top: 22px;
+}
+
+.tracker-step {
+ align-items: center;
+ display: flex;
+ flex-direction: column;
+ gap: 4px;
+ min-width: 0;
+ position: relative;
+ text-align: center;
+ z-index: 1;
+}
+
+.tracker-step-icon {
+ align-items: center;
+ background: #d0d5dd;
+ border-radius: 999px;
+ color: #475467;
+ display: flex;
+ height: 44px;
+ justify-content: center;
+ margin-bottom: 4px;
+ width: 44px;
+}
+
+.tracker-step.is-done .tracker-step-icon {
+ background: #2563eb;
+ color: #fff;
+}
+
+.tracker-step strong {
+ color: #172033;
+ font-size: 12px;
+ line-height: 1.2;
+}
+
+.tracker-step span {
+ color: #667085;
+ font-size: 11px;
+ line-height: 1.2;
+ max-width: 120px;
+ overflow-wrap: anywhere;
+}
+
+.tracker-grid {
+ display: grid;
+ gap: 14px;
+ grid-template-columns: minmax(0, 1.2fr) minmax(320px, .8fr);
+}
+
+.tracker-section-head {
+ border-bottom: 1px solid #e6edf5;
+ margin: -2px -16px 12px;
+ padding: 0 16px 12px;
+}
+
+.tracker-section-head h4 {
+ color: #172033;
+ font-size: 16px;
+ font-weight: 700;
+ margin: 0;
+}
+
+.tracker-section-head > span {
+ align-items: center;
+ background: #eef2f7;
+ border-radius: 999px;
+ color: #344054;
+ display: inline-flex;
+ font-size: 12px;
+ font-weight: 700;
+ height: 24px;
+ justify-content: center;
+ min-width: 24px;
+ padding: 0 8px;
+}
+
+.tracker-mini-table {
+ overflow-x: auto;
+}
+
+.tracker-mini-table .table {
+ margin: 0;
+}
+
+.tracker-mini-table th {
+ color: #344054;
+ font-size: 12px;
+ white-space: nowrap;
+}
+
+.tracker-mini-table td {
+ color: #344054;
+ font-size: 12px;
+ vertical-align: middle;
+}
+
+.tracker-badge {
+ border-radius: 999px;
+ display: inline-flex;
+ font-size: 12px;
+ font-weight: 700;
+ line-height: 1;
+ padding: 7px 10px;
+ white-space: nowrap;
+}
+
+.tracker-badge.is-success {
+ background: #dcfce7;
+ color: #15803d;
+}
+
+.tracker-badge.is-warning {
+ background: #fef3c7;
+ color: #b45309;
+}
+
+.tracker-badge.is-danger {
+ background: #fee2e2;
+ color: #b42318;
+}
+
+.tracker-badge.is-info {
+ background: #dbeafe;
+ color: #1d4ed8;
+}
+
+.tracker-order-line {
+ align-items: center;
+ border: 1px solid #e6edf5;
+ border-radius: 6px;
+ display: grid;
+ gap: 10px;
+ grid-template-columns: 120px minmax(0, 1fr) auto;
+ padding: 10px 12px;
+}
+
+.tracker-order-line span {
+ color: #344054;
+ overflow-wrap: anywhere;
+}
+
+.tracker-order-line em {
+ color: #172033;
+ font-style: normal;
+ font-weight: 700;
+}
+
+.tracker-muted,
+.tracker-updated {
+ color: #667085;
+ font-size: 12px;
+ margin-top: 10px;
+}
+
+.tracker-approval-list {
+ list-style: none;
+ margin: 0;
+ padding: 0;
+}
+
+.tracker-approval-list li {
+ align-items: flex-start;
+ display: flex;
+ gap: 10px;
+ padding: 9px 0;
+}
+
+.tracker-approval-list li + li {
+ border-top: 1px solid #eef2f7;
+}
+
+.tracker-approval-dot {
+ align-items: center;
+ border-radius: 999px;
+ display: inline-flex;
+ flex: 0 0 24px;
+ font-size: 12px;
+ font-weight: 700;
+ height: 24px;
+ justify-content: center;
+ width: 24px;
+}
+
+.tracker-approval-list .is-approved .tracker-approval-dot {
+ background: #16a34a;
+ color: #fff;
+}
+
+.tracker-approval-list .is-waiting .tracker-approval-dot {
+ background: #fef3c7;
+ color: #b45309;
+}
+
+.tracker-approval-list strong {
+ color: #172033;
+ display: block;
+ font-size: 13px;
+}
+
+.tracker-approval-list small {
+ color: #667085;
+ display: block;
+ font-size: 12px;
+ margin-top: 3px;
+}
+
+.tracker-resume {
+ display: grid;
+ gap: 10px 16px;
+ grid-template-columns: 150px minmax(0, 1fr);
+ margin: 0;
+}
+
+.tracker-resume dt {
+ color: #667085;
+ font-weight: 600;
+}
+
+.tracker-resume dd {
+ color: #172033;
+ font-weight: 600;
+ margin: 0;
+ overflow-wrap: anywhere;
+}
+
+.tracker-state,
+.tracker-empty-inline {
+ align-items: center;
+ background: #fff;
+ border: 1px dashed #cfd8e3;
+ border-radius: 8px;
+ color: #667085;
+ display: flex;
+ gap: 8px;
+ justify-content: center;
+ min-height: 80px;
+ padding: 16px;
+ text-align: center;
+}
+
+.tracker-empty-inline {
+ background: #fbfcfe;
+ min-height: 74px;
+}
+
+@media (max-width: 992px) {
+ .tracker-summary-grid,
+ .tracker-grid {
+ grid-template-columns: 1fr;
+ }
+
+ .tracker-steps {
+ gap: 12px;
+ grid-template-columns: repeat(3, minmax(0, 1fr));
+ }
+
+ .tracker-steps:before {
+ display: none;
+ }
+}
+
+@media (max-width: 640px) {
+ .tracker-shell {
+ padding: 12px;
+ }
+
+ .tracker-header {
+ align-items: flex-start;
+ flex-direction: column;
+ }
+
+ .tracker-refresh {
+ width: 100%;
+ }
+
+ .tracker-steps {
+ grid-template-columns: repeat(2, minmax(0, 1fr));
+ }
+
+ .tracker-order-line,
+ .tracker-resume {
+ grid-template-columns: 1fr;
+ }
+}
diff --git a/compras_digital/wcm/widget/widget_solicitacoes/src/main/webapp/resources/js/widget_solicitacoes.js b/compras_digital/wcm/widget/widget_solicitacoes/src/main/webapp/resources/js/widget_solicitacoes.js
index 36c640d..2ae7491 100644
--- a/compras_digital/wcm/widget/widget_solicitacoes/src/main/webapp/resources/js/widget_solicitacoes.js
+++ b/compras_digital/wcm/widget/widget_solicitacoes/src/main/webapp/resources/js/widget_solicitacoes.js
@@ -1,55 +1,636 @@
var MyWidget = SuperWidget.extend({
-
- // Variáveis do widget (se precisar salvar estado entre chamadas)
instanceId: null,
- // Método iniciado quando o widget é carregado
init: function() {
- this.instanceId = this.instanceId || new Date().getTime();
- console.log("Widget Solicitações carregado, instância:", this.instanceId);
+ this.clearMessage();
+ $("#detalheSolicitacao_" + this.instanceId).hide();
},
-
- // BIND de eventos
+
bindings: {
local: {
- 'pesquisar': ['click_consultarSolicitacoes']
+ "pesquisar": ["click_consultarSolicitacoes"],
+ "acompanhar": ["click_acompanharSolicitacao"],
+ "limpar": ["click_limparConsulta"]
},
global: {}
},
-
- // Função chamada ao clicar em "Pesquisar"
+
consultarSolicitacoes: function(htmlElement, event) {
- var numero = $("#filtroNumero_" + this.instanceId).val();
- var solicitante = $("#filtroSolicitante_" + this.instanceId).val();
- var status = $("#filtroStatus_" + this.instanceId).val();
+ if (event) event.preventDefault();
- var constraints = [];
- if (numero) constraints.push(DatasetFactory.createConstraint("C1_NUM", numero, numero, ConstraintType.MUST));
- if (solicitante) constraints.push(DatasetFactory.createConstraint("C1_SOLICIT", solicitante, solicitante, ConstraintType.MUST));
- if (status) constraints.push(DatasetFactory.createConstraint("STATUS", status, status, ConstraintType.MUST));
+ var numero = this.normalizarTexto($("#filtroNumero_" + this.instanceId).val());
+ var solicitante = this.normalizarTexto($("#filtroSolicitante_" + this.instanceId).val());
+ var status = this.normalizarTexto($("#filtroStatus_" + this.instanceId).val());
- var ds = DatasetFactory.getDataset("dsSolicitacoesCompra", null, constraints, null);
+ this.clearMessage();
+ $("#detalheSolicitacao_" + this.instanceId).hide().empty();
- let html = `
-
- | Número | Solicitante | Data | Status | Pedido |
-
`;
-
- if (ds && ds.values.length) {
- ds.values.forEach(sc => {
- html += `
- | ${sc.C1_NUM} |
- ${sc.C1_SOLICIT} |
- ${sc.C1_EMISSAO} |
- ${sc.STATUS} |
- ${sc.C1_PEDIDO || '-'} |
-
`;
- });
- } else {
- html += `| Nenhuma solicitação encontrada |
`;
+ if (numero) {
+ this.renderizarConsultaPorNumero(numero);
+ return;
}
- html += `
`;
- $("#listaSolicitacoes_" + this.instanceId).html(html);
+ this.renderizarListaGenerica(solicitante, status);
+ },
+
+ acompanharSolicitacao: function(htmlElement, event) {
+ if (event) event.preventDefault();
+
+ var numero = $(htmlElement).attr("data-numero-sc");
+ if (!numero) return;
+
+ $("#filtroNumero_" + this.instanceId).val(numero);
+ this.renderizarTracker(numero);
+ },
+
+ limparConsulta: function(htmlElement, event) {
+ if (event) event.preventDefault();
+
+ $("#filtroNumero_" + this.instanceId).val("");
+ $("#filtroSolicitante_" + this.instanceId).val("");
+ $("#filtroStatus_" + this.instanceId).val("");
+ $("#listaSolicitacoes_" + this.instanceId).empty();
+ $("#detalheSolicitacao_" + this.instanceId).hide().empty();
+ this.clearMessage();
+ },
+
+ bindDynamicActions: function() {
+ var self = this;
+ $("#listaSolicitacoes_" + this.instanceId)
+ .find("[data-acompanhar]")
+ .off("click.tracker")
+ .on("click.tracker", function(event) {
+ self.acompanharSolicitacao(this, event);
+ });
+ },
+
+ renderizarConsultaPorNumero: function(numero) {
+ var dados = this.consultarSC(numero);
+
+ if (!dados || !dados.rows.length || !this.temSCValida(dados.rows[0])) {
+ $("#listaSolicitacoes_" + this.instanceId).html(this.emptyState("Nenhuma solicitacao encontrada para a SC informada."));
+ return;
+ }
+
+ $("#listaSolicitacoes_" + this.instanceId).html(this.montarTabelaSolicitacoes(dados.rows));
+ this.bindDynamicActions();
+ this.renderizarTracker(numero, dados);
+ },
+
+ renderizarListaGenerica: function(solicitante, status) {
+ var ds = null;
+ var constraints = [];
+
+ try {
+ if (solicitante) constraints.push(this.criarConstraint("C1_SOLICIT", solicitante, solicitante));
+ if (status) constraints.push(this.criarConstraint("STATUS", status, status));
+ ds = this.buscarDataset("dsSolicitacoesCompra", null, constraints, null);
+ } catch (e) {
+ ds = null;
+ }
+
+ if (!ds || !ds.values || !ds.values.length) {
+ this.showMessage("Informe o numero da SC para abrir o tracker. A listagem geral depende de um dataset de consulta de solicitacoes no ambiente Fluig.", "info");
+ $("#listaSolicitacoes_" + this.instanceId).html(this.emptyState("Digite uma SC e clique em Pesquisar."));
+ return;
+ }
+
+ $("#listaSolicitacoes_" + this.instanceId).html(this.montarTabelaSolicitacoes(ds.values));
+ this.bindDynamicActions();
+ },
+
+ consultarSC: function(numero) {
+ var constraints = [
+ this.criarConstraint("numeroSCProtheus", numero, numero)
+ ];
+ var ds = this.buscarDataset("ds_consultaSC", null, constraints, null);
+
+ return {
+ dataset: ds,
+ rows: ds && ds.values ? ds.values : []
+ };
+ },
+
+ criarConstraint: function(campo, valorInicial, valorFinal) {
+ if (typeof DatasetFactory !== "undefined" && typeof ConstraintType !== "undefined") {
+ return DatasetFactory.createConstraint(campo, valorInicial, valorFinal, ConstraintType.MUST);
+ }
+
+ return {
+ _field: campo,
+ _initialValue: valorInicial,
+ _finalValue: valorFinal,
+ _type: 1,
+ fieldName: campo,
+ initialValue: valorInicial,
+ finalValue: valorFinal,
+ constraintType: 1
+ };
+ },
+
+ buscarDataset: function(nome, fields, constraints, sortFields) {
+ if (typeof DatasetFactory !== "undefined") {
+ return DatasetFactory.getDataset(nome, fields, constraints, sortFields);
+ }
+
+ var retorno = { values: [] };
+
+ $.ajax({
+ url: "/api/public/ecm/dataset/datasets",
+ type: "POST",
+ async: false,
+ contentType: "application/json",
+ dataType: "json",
+ data: JSON.stringify({
+ name: nome,
+ fields: fields || null,
+ constraints: constraints || [],
+ order: sortFields || null
+ }),
+ success: function(response) {
+ var content = response && response.content ? response.content : response;
+ retorno = {
+ values: content && content.values ? content.values : []
+ };
+ },
+ error: function(xhr) {
+ var mensagem = xhr && xhr.responseText ? xhr.responseText : "Falha ao consultar dataset " + nome;
+ throw new Error(mensagem);
+ }
+ });
+
+ return retorno;
+ },
+
+ renderizarTracker: function(numero, dadosConsulta) {
+ var detalhe = $("#detalheSolicitacao_" + this.instanceId);
+ detalhe.show().html(this.loadingState("Consultando dados da SC " + this.escapeHTML(numero) + "..."));
+
+ try {
+ var dados = dadosConsulta || this.consultarSC(numero);
+ if (!dados || !dados.rows.length || !this.temSCValida(dados.rows[0])) {
+ detalhe.html(this.emptyState("Nao foi possivel carregar o tracker desta SC."));
+ return;
+ }
+
+ var resumo = this.montarResumoSC(dados.rows);
+ detalhe.html(this.montarTracker(resumo));
+ } catch (e) {
+ detalhe.html(this.emptyState("Erro ao carregar o tracker: " + this.escapeHTML(String(e))));
+ }
+ },
+
+ montarTabelaSolicitacoes: function(rows) {
+ var exibidos = {};
+ var html = [
+ '
',
+ '
',
+ '',
+ '| Solicitacao | ',
+ 'Solicitante | ',
+ 'Data | ',
+ 'Status | ',
+ 'Pedido | ',
+ 'Acao | ',
+ '
'
+ ];
+
+ for (var i = 0; i < rows.length; i++) {
+ var row = rows[i] || {};
+ var numero = this.primeiroValor(row.C1_NUM, row.numero, row.NUMERO);
+ if (!numero) continue;
+ if (exibidos[numero]) continue;
+ exibidos[numero] = true;
+
+ html.push(
+ '',
+ '| SC ' + this.escapeHTML(numero) + ' | ',
+ '' + this.escapeHTML(this.primeiroValor(row.C1_SOLICIT, row.solicitante, "-")) + ' | ',
+ '' + this.escapeHTML(this.formatarData(this.primeiroValor(row.C1_EMISSAO, row.data, ""))) + ' | ',
+ '' + this.montarBadge(this.primeiroValor(row.STATUS, row.status, "-")) + ' | ',
+ '' + this.escapeHTML(this.formatarDocumento(this.primeiroValor(row.C1_PEDIDO, row.pedido, "-"))) + ' | ',
+ '',
+ '',
+ ' | ',
+ '
'
+ );
+ }
+
+ html.push('
');
+ return html.join("");
+ },
+
+ montarResumoSC: function(rows) {
+ var base = rows[0] || {};
+ var cotacoes = this.parseJsonArray(base.COTACOES_JSON);
+ var pedidos = this.parseJsonArray(base.PEDIDO_JSON);
+ var totalSC = this.somarCampo(rows, "C1_TOTAL");
+ var menorCotacao = this.encontrarMenorCotacao(cotacoes);
+ var pedido = this.formatarDocumento(this.primeiroValor(base.C1_PEDIDO, menorCotacao ? menorCotacao.C8_NUMPED : ""));
+ var cotacao = this.formatarDocumento(this.primeiroValor(base.C1_COTACAO, menorCotacao ? menorCotacao.C8_NUM : ""));
+ var status = this.definirStatus(base, cotacao, pedido);
+ var assinaturas = this.extrairAssinaturasPedido(pedidos);
+
+ return {
+ numero: this.primeiroValor(base.C1_NUM, ""),
+ solicitante: this.primeiroValor(base.C1_SOLICIT, "-"),
+ data: this.formatarData(base.C1_EMISSAO),
+ valor: totalSC > 0 ? this.formatarMoeda(totalSC) : this.formatarMoeda(this.numeroBR(base.C1_TOTAL)),
+ status: status,
+ cotacao: cotacao,
+ pedido: pedido,
+ fornecedor: menorCotacao ? this.primeiroValor(menorCotacao.A2_NOME, menorCotacao.C8_FORNOME, menorCotacao.C8_FORNECE, "-") : "-",
+ menorValor: menorCotacao ? this.formatarMoeda(this.numeroBR(menorCotacao.C8_TOTAL)) : "-",
+ itens: rows,
+ cotacoes: cotacoes,
+ pedidos: pedidos,
+ assinaturas: assinaturas,
+ cotacaoErro: base.COTACAO_ERRO || "",
+ pedidoErro: base.PEDIDO_ERRO || "",
+ atualizadoEm: this.montarDataHora(base.data_consulta, base.hora_consulta)
+ };
+ },
+
+ montarTracker: function(resumo) {
+ var etapas = this.montarEtapas(resumo);
+
+ return [
+ '
',
+ '',
+ '
',
+ '
SC ' + this.escapeHTML(resumo.numero || "-") + '
',
+ 'Acompanhamento completo da solicitacao',
+ '',
+ this.montarBadge(resumo.status),
+ '
',
+ '',
+ this.montarInfo("Solicitante", resumo.solicitante),
+ this.montarInfo("Data da solicitacao", resumo.data || "-"),
+ this.montarInfo("Valor estimado", resumo.valor || "-"),
+ this.montarInfo("Cotacao", resumo.cotacao || "-"),
+ this.montarInfo("Pedido", resumo.pedido || "-"),
+ this.montarInfo("Fornecedor sugerido", resumo.fornecedor || "-"),
+ '
',
+ '',
+ '
',
+ '' + etapas.join("") + '
',
+ '',
+ '
',
+ '
',
+ this.montarCotacoes(resumo),
+ this.montarPedidos(resumo),
+ this.montarItens(resumo),
+ '
',
+ '
',
+ this.montarAprovacoes(resumo),
+ this.montarResumoFinal(resumo),
+ '
',
+ '
'
+ ].join("");
+ },
+
+ montarEtapas: function(resumo) {
+ var temCotacao = this.documentoValido(resumo.cotacao);
+ var temPedido = this.documentoValido(resumo.pedido);
+ var aprovado = resumo.assinaturas.length > 0 && this.todasAssinaturasAprovadas(resumo.assinaturas);
+
+ return [
+ this.montarEtapa("Solicitacao", "Criada", true, "fluigicon-shopping-cart"),
+ this.montarEtapa("Cotacao", temCotacao ? resumo.cotacao : "Pendente", temCotacao, "fluigicon-link"),
+ this.montarEtapa("Pedido", temPedido ? resumo.pedido : "Aguardando", temPedido, "fluigicon-file"),
+ this.montarEtapa("Aprovacao", aprovado ? "Aprovado" : "Pendente", aprovado, "fluigicon-ok-circle"),
+ this.montarEtapa("Entrega", "Aguardando", false, "fluigicon-truck")
+ ];
+ },
+
+ montarEtapa: function(titulo, detalhe, concluida, icone) {
+ return [
+ '
',
+ '
',
+ '
' + this.escapeHTML(titulo) + '',
+ '
' + this.escapeHTML(detalhe || "-") + '',
+ '
'
+ ].join("");
+ },
+
+ montarCotacoes: function(resumo) {
+ var cotacoes = resumo.cotacoes || [];
+ var html = [
+ '
',
+ 'Cotacoes
' + cotacoes.length + ''
+ ];
+
+ if (!cotacoes.length) {
+ html.push(this.emptyInline(resumo.cotacaoErro || "Nenhuma cotacao vinculada ate o momento."));
+ } else {
+ html.push('| Fornecedor | Item | Valor | Pedido |
');
+ for (var i = 0; i < Math.min(cotacoes.length, 5); i++) {
+ var c = cotacoes[i] || {};
+ html.push(
+ '',
+ '| ' + this.escapeHTML(this.primeiroValor(c.A2_NOME, c.C8_FORNOME, c.C8_FORNECE, "-")) + ' | ',
+ '' + this.escapeHTML(this.primeiroValor(c.C8_ITEM, c.C8_ITEMSC, "-")) + ' | ',
+ '' + this.escapeHTML(this.formatarMoeda(this.numeroBR(c.C8_TOTAL))) + ' | ',
+ '' + this.escapeHTML(this.formatarDocumento(c.C8_NUMPED || "-")) + ' | ',
+ '
'
+ );
+ }
+ html.push('
');
+ }
+
+ html.push('');
+ return html.join("");
+ },
+
+ montarPedidos: function(resumo) {
+ var pedidos = resumo.pedidos || [];
+ var html = [
+ '
',
+ 'Pedidos
' + (this.documentoValido(resumo.pedido) ? "1" : "0") + ''
+ ];
+
+ if (!this.documentoValido(resumo.pedido)) {
+ html.push(this.emptyInline(resumo.pedidoErro || "Pedido ainda nao gerado."));
+ } else {
+ html.push('PED ' + this.escapeHTML(resumo.pedido) + '' + this.escapeHTML(resumo.fornecedor) + '' + this.escapeHTML(resumo.menorValor) + '
');
+ if (pedidos.length) {
+ html.push('' + this.escapeHTML(pedidos.length + " registro(s) retornado(s) pela consulta do pedido.") + '
');
+ }
+ }
+
+ html.push('');
+ return html.join("");
+ },
+
+ montarAprovacoes: function(resumo) {
+ var assinaturas = resumo.assinaturas || [];
+ var html = [
+ '
',
+ 'Aprovacoes
' + assinaturas.length + ''
+ ];
+
+ if (!assinaturas.length) {
+ html.push(this.emptyInline("Sem alcadas retornadas para o pedido."));
+ } else {
+ html.push('');
+ for (var i = 0; i < assinaturas.length; i++) {
+ var a = assinaturas[i] || {};
+ var aprovado = this.statusAprovado(a.status);
+ html.push(
+ '- ',
+ '' + (aprovado ? "✓" : "!") + '',
+ '
' + this.escapeHTML(this.primeiroValor(a.nivel, "Nivel " + (i + 1))) + ' - ' + this.escapeHTML(this.primeiroValor(a.usuario, a.nome, "-")) + '',
+ '' + this.escapeHTML(this.primeiroValor(a.status, a.descricao, "Pendente")) + '
',
+ ' '
+ );
+ }
+ html.push('
');
+ }
+
+ html.push('');
+ return html.join("");
+ },
+
+ montarItens: function(resumo) {
+ var itens = resumo.itens || [];
+ var html = [
+ '
',
+ 'Itens da solicitacao
' + itens.length + '',
+ '| Item | Descricao | Qtd. | Total |
'
+ ];
+
+ for (var i = 0; i < itens.length; i++) {
+ var item = itens[i] || {};
+ html.push(
+ '',
+ '| ' + this.escapeHTML(this.primeiroValor(item.C1_ITEM, "-")) + ' | ',
+ '' + this.escapeHTML(this.primeiroValor(item.C1_DESCRI, item.C1_PRODUTO, "-")) + ' | ',
+ '' + this.escapeHTML(this.primeiroValor(item.C1_QUANT, "-")) + ' | ',
+ '' + this.escapeHTML(this.formatarMoeda(this.numeroBR(item.C1_TOTAL))) + ' | ',
+ '
'
+ );
+ }
+
+ html.push('
');
+ return html.join("");
+ },
+
+ montarResumoFinal: function(resumo) {
+ return [
+ '
',
+ 'Resumo
',
+ '',
+ '- Status da SC
- ' + this.montarBadge(resumo.status) + '
',
+ '- Menor valor encontrado
- ' + this.escapeHTML(resumo.menorValor || "-") + '
',
+ '- Fornecedor sugerido
- ' + this.escapeHTML(resumo.fornecedor || "-") + '
',
+ '- Pedido gerado
- ' + this.escapeHTML(resumo.pedido || "-") + '
',
+ '- Previsao de entrega
- A definir
',
+ '
',
+ resumo.atualizadoEm ? 'Ultima atualizacao: ' + this.escapeHTML(resumo.atualizadoEm) + '
' : '',
+ ''
+ ].join("");
+ },
+
+ montarInfo: function(label, valor) {
+ return '
' + this.escapeHTML(label) + '' + this.escapeHTML(valor || "-") + '
';
+ },
+
+ montarBadge: function(texto) {
+ var t = this.primeiroValor(texto, "-");
+ var c = "tracker-badge";
+ var s = String(t).toLowerCase();
+
+ if (s.indexOf("aprov") >= 0 || s.indexOf("gerad") >= 0 || s.indexOf("liberad") >= 0 || s.indexOf("sucesso") >= 0) c += " is-success";
+ else if (s.indexOf("aguard") >= 0 || s.indexOf("pend") >= 0 || s.indexOf("cotacao") >= 0) c += " is-warning";
+ else if (s.indexOf("reprov") >= 0 || s.indexOf("erro") >= 0) c += " is-danger";
+ else c += " is-info";
+
+ return '
' + this.escapeHTML(t) + '';
+ },
+
+ definirStatus: function(row, cotacao, pedido) {
+ if (this.documentoValido(pedido)) return "Pedido gerado";
+ if (this.documentoValido(cotacao)) return "Cotacao gerada";
+
+ var aprov = String(row.C1_APROV || "").toUpperCase();
+ if (aprov === "L") return "Liberada";
+ if (aprov === "R") return "Reprovada";
+ if (aprov === "B") return "Aguardando cotacao";
+
+ return this.primeiroValor(row.STATUS, "Aguardando acompanhamento");
+ },
+
+ encontrarMenorCotacao: function(cotacoes) {
+ var menor = null;
+ var menorValor = null;
+
+ for (var i = 0; i < cotacoes.length; i++) {
+ var atual = cotacoes[i] || {};
+ var valor = this.numeroBR(atual.C8_TOTAL);
+ if (!valor && valor !== 0) continue;
+
+ if (menor === null || valor < menorValor) {
+ menor = atual;
+ menorValor = valor;
+ }
+ }
+
+ return menor;
+ },
+
+ extrairAssinaturasPedido: function(pedidos) {
+ var assinaturas = [];
+
+ for (var i = 0; i < pedidos.length; i++) {
+ var p = pedidos[i] || {};
+ var candidatos = [p.ALCADAS, p.alcadas, p.aprovacoes, p.APROVACOES, p.assinaturas, p.ASSINATURAS];
+
+ for (var j = 0; j < candidatos.length; j++) {
+ var lista = candidatos[j];
+ if (typeof lista === "string") lista = this.parseJsonArray(lista);
+ if (lista && lista.length) {
+ for (var k = 0; k < lista.length; k++) {
+ var a = lista[k] || {};
+ assinaturas.push({
+ nivel: this.primeiroValor(a.NIVEL, a.nivel, a.SEQUENCIA, a.sequencia),
+ usuario: this.primeiroValor(a.USUARIO, a.usuario, a.NOME, a.nome, a.APROVADOR, a.aprovador),
+ status: this.primeiroValor(a.STATUS, a.status, a.SITUACAO, a.situacao, a.DESCRICAO, a.descricao)
+ });
+ }
+ }
+ }
+ }
+
+ return assinaturas;
+ },
+
+ todasAssinaturasAprovadas: function(assinaturas) {
+ for (var i = 0; i < assinaturas.length; i++) {
+ if (!this.statusAprovado(assinaturas[i].status)) return false;
+ }
+ return assinaturas.length > 0;
+ },
+
+ statusAprovado: function(status) {
+ var s = String(status || "").toLowerCase();
+ return s.indexOf("aprov") >= 0 || s === "03" || s.indexOf("liberad") >= 0;
+ },
+
+ temSCValida: function(row) {
+ return !!(row && this.primeiroValor(row.C1_NUM, row.numero, row.NUMERO));
+ },
+
+ documentoValido: function(valor) {
+ var v = String(valor || "").replace(/\s/g, "");
+ if (!v || v === "-") return false;
+ if (/^0+$/.test(v)) return false;
+ if (/^x+$/i.test(v)) return false;
+ return true;
+ },
+
+ parseJsonArray: function(valor) {
+ if (!valor) return [];
+ if (Object.prototype.toString.call(valor) === "[object Array]") return valor;
+
+ try {
+ var parsed = JSON.parse(valor);
+ if (Object.prototype.toString.call(parsed) === "[object Array]") return parsed;
+ if (parsed && parsed.pedidos) return parsed.pedidos;
+ if (parsed && parsed.cotacoes) return parsed.cotacoes;
+ if (parsed && parsed.values) return parsed.values;
+ } catch (e) {
+ return [];
+ }
+
+ return [];
+ },
+
+ somarCampo: function(rows, campo) {
+ var total = 0;
+ for (var i = 0; i < rows.length; i++) {
+ total += this.numeroBR((rows[i] || {})[campo]);
+ }
+ return total;
+ },
+
+ numeroBR: function(valor) {
+ if (typeof valor === "number") return valor;
+ var v = String(valor || "").trim();
+ if (!v) return 0;
+
+ v = v.replace(/[R$\s]/g, "");
+ if (v.indexOf(",") >= 0) v = v.replace(/\./g, "").replace(",", ".");
+ var n = parseFloat(v);
+ return isNaN(n) ? 0 : n;
+ },
+
+ formatarMoeda: function(valor) {
+ var n = typeof valor === "number" ? valor : this.numeroBR(valor);
+ if (!n && n !== 0) return "-";
+ return "R$ " + n.toLocaleString("pt-BR", { minimumFractionDigits: 2, maximumFractionDigits: 2 });
+ },
+
+ formatarData: function(valor) {
+ var v = String(valor || "").trim();
+ if (!v) return "-";
+ if (/^\d{8}$/.test(v)) return v.substr(6, 2) + "/" + v.substr(4, 2) + "/" + v.substr(0, 4);
+ return v;
+ },
+
+ formatarDocumento: function(valor) {
+ var v = String(valor || "").trim();
+ if (!this.documentoValido(v)) return "-";
+ return v;
+ },
+
+ montarDataHora: function(data, hora) {
+ var d = this.formatarData(data);
+ var h = String(hora || "").trim();
+ if (d === "-" && !h) return "";
+ return h ? d + " " + h : d;
+ },
+
+ primeiroValor: function() {
+ for (var i = 0; i < arguments.length; i++) {
+ var v = arguments[i];
+ if (v !== null && v !== undefined && String(v).trim() !== "") return String(v).trim();
+ }
+ return "";
+ },
+
+ normalizarTexto: function(valor) {
+ return String(valor || "").trim();
+ },
+
+ showMessage: function(texto, tipo) {
+ var classe = tipo === "danger" ? "alert-danger" : tipo === "success" ? "alert-success" : "alert-info";
+ $("#mensagemSolicitacoes_" + this.instanceId).html('
' + this.escapeHTML(texto) + '
');
+ },
+
+ clearMessage: function() {
+ $("#mensagemSolicitacoes_" + this.instanceId).empty();
+ },
+
+ loadingState: function(texto) {
+ return '
' + this.escapeHTML(texto) + '
';
+ },
+
+ emptyState: function(texto) {
+ return '
' + this.escapeHTML(texto) + '
';
+ },
+
+ emptyInline: function(texto) {
+ return '
' + this.escapeHTML(texto) + '
';
+ },
+
+ escapeHTML: function(valor) {
+ return String(valor === null || valor === undefined ? "" : valor)
+ .replace(/&/g, "&")
+ .replace(//g, ">")
+ .replace(/"/g, """)
+ .replace(/'/g, "'");
}
});